Rで有限要素法:片持ち梁-中間区間の逆三角形状分布荷重:たわみ量

本ポストはこちらの続きです。

Rで有限要素法:片持ち梁-中間区間の三角形状分布荷重:たわみ量
const typesetMath = (el) => { if (window.MathJax) { // MathJax Typeset window.MathJax.typeset(); } else if (window.katex...

片持ち梁-中間区間の逆三角形状分布荷重

Figure 1: 片持ち梁-中間区間の逆三角形状分布荷重

片持ち梁のたわみ:FEM(オイラー・ベルヌーイ梁要素) vs 厳密解

ガウス求積の評価点の個数 \(\,n\)、位置 \(\xi_i\) そして重み \(w_i\)につきましては、https://pomax.github.io/bezierinfo/legendre-gauss.html から引用しています。

# ============================================================
# 片持ち梁のたわみ(中間区間の逆三角形分布荷重):FEM vs 厳密解
# ============================================================
#
# 厳密解(xは自由端Aから測った距離。区間ごとに式が異なる):
#   w1 = (p0b/120EI){20c^3+50c^2b+40cb^2+11b^3+5(6c^2+8cb+3b^2)(a-x)}   [0<=x<=a]
#   w2 = (p0b/120EI){20c^3+20c^2b-4b^3+5(6c^2+8cb+3b^2)(a+b-x)
#                     +(5/b)(x-a)^4-(1/b^2)(x-a)^5}                     [a<=x<=a+b]
#   w3 = (p0b/12EI){(3c+2b)(l-x)^2-(l-x)^3}                             [a+b<=x<=l]
#   w_max = (p0b/120EI){20c^3+50bc^2+40b^2c+11b^3+5(6c^2+8cb+3b^2)a}    [x=0, 自由端]
#
# 荷重はx=aで最大p0、x=a+bでゼロとなる直線的な分布として定義する:
#   q(x) = p0*(1-(x-a)/b)   [a<=x<=a+b]、それ以外は0

library(ggplot2)

# ------------------------------------------------------------
# 1. 梁の諸元と荷重の設定
# ------------------------------------------------------------
l <- 2.0
a <- 0.4
b <- 0.8
c <- l - a - b
p0 <- 600 # 荷重区間の左端(x=a)での最大強度 [N/m]
E <- 210e9
I <- 4.1667e-6
EI <- E * I

# 分布荷重をxの関数として定義(自由端起点)。区間[a,a+b]でp0から0まで直線的に減少。
q_of_x <- function(x) {
  ifelse(x < a | x > a + b, 0, p0 * (1 - (x - a) / b))
}
q_dist <- function(s) q_of_x(l - s) # FEM座標s(固定端起点)の関数に変換

# ------------------------------------------------------------
# 2. 形状関数と要素剛性行列
# ------------------------------------------------------------
shape_N <- function(xi, Le) {
  N1 <- 1 - 3 * xi^2 + 2 * xi^3
  N2 <- Le * (xi - 2 * xi^2 + xi^3)
  N3 <- 3 * xi^2 - 2 * xi^3
  N4 <- Le * (-xi^2 + xi^3)
  c(N1, N2, N3, N4)
}

beam_element_k <- function(Le) {
  (EI / Le^3) * matrix(c(
    12, 6 * Le, -12, 6 * Le,
    6 * Le, 4 * Le^2, -6 * Le, 2 * Le^2,
    -12, -6 * Le, 12, -6 * Le,
    6 * Le, 2 * Le^2, -6 * Le, 4 * Le^2
  ), nrow = 4, byrow = TRUE)
}

# ------------------------------------------------------------
# 3. 等価節点荷重をガウス求積で数値的に計算する(6点ガウス求積)
# ------------------------------------------------------------
gauss_pts <- c(
  -0.9324695142031521, -0.6612093864662645, -0.2386191860831969,
  0.2386191860831969, 0.6612093864662645, 0.9324695142031521
)
gauss_wts <- c(
  0.1713244923791704, 0.3607615730481386, 0.4679139345726910,
  0.4679139345726910, 0.3607615730481386, 0.1713244923791704
)

beam_element_f <- function(s0, Le) {
  f_e <- numeric(4)
  for (k in seq_along(gauss_pts)) {
    xi <- (gauss_pts[k] + 1) / 2
    jac <- Le / 2
    s <- s0 + xi * Le
    q <- q_dist(s)
    f_e <- f_e + shape_N(xi, Le) * q * jac * gauss_wts[k]
  }
  f_e
}

# ------------------------------------------------------------
# 4. メッシュ生成(荷重区間の境界にちょうど節点が来るように要素数を選ぶ)
# ------------------------------------------------------------
n_elem <- 20L
Le <- l / n_elem
n_node <- n_elem + 1L
n_dof <- 2L * n_node

K <- matrix(0, n_dof, n_dof)
F <- numeric(n_dof)
K_e <- beam_element_k(Le)

for (e in seq_len(n_elem)) {
  s0 <- (e - 1) * Le
  f_e <- beam_element_f(s0, Le)
  dofs <- c(2 * e - 1, 2 * e, 2 * e + 1, 2 * e + 2)
  K[dofs, dofs] <- K[dofs, dofs] + K_e
  F[dofs] <- F[dofs] + f_e
}

# ------------------------------------------------------------
# 5. 境界条件(固定端: w=0, θ=0)
# ------------------------------------------------------------
fixed_dofs <- c(1, 2)
free_dofs <- setdiff(seq_len(n_dof), fixed_dofs)

u <- numeric(n_dof)
u[free_dofs] <- solve(K[free_dofs, free_dofs], F[free_dofs])

w_fem <- u[seq(1, n_dof, by = 2)]
th_fem <- u[seq(2, n_dof, by = 2)]

s_nodes <- seq(0, l, length.out = n_node)
x_nodes <- l - s_nodes

# ------------------------------------------------------------
# 6. 厳密解との比較(区間ごとに式を使い分ける)
# ------------------------------------------------------------
w_exact_fn <- function(x) {
  lx <- l - x
  ifelse(
    x <= a,
    (p0 * b) / (120 * EI) * (20 * c^3 + 50 * c^2 * b + 40 * c * b^2 + 11 * b^3 + 5 * (6 * c^2 + 8 * c * b + 3 * b^2) * (a - x)),
    ifelse(
      x <= a + b,
      (p0 * b) / (120 * EI) * (20 * c^3 + 20 * c^2 * b - 4 * b^3 + 5 * (6 * c^2 + 8 * c * b + 3 * b^2) * (a + b - x)
        + (5 / b) * (x - a)^4 - (1 / b^2) * (x - a)^5),
      (p0 * b) / (12 * EI) * ((3 * c + 2 * b) * lx^2 - lx^3)
    )
  )
}

comparison <- data.frame(
  自由端起点_x_m = round(x_nodes, 3),
  FEM近似解_mm = round(w_fem * 1000, 8),
  厳密解_mm = round(w_exact_fn(x_nodes) * 1000, 8),
  差_mm = w_fem * 1000 - w_exact_fn(x_nodes) * 1000
)
print(comparison)

cat("\n自由端でのたわみ量:\n")
cat("  FEM近似解:", w_fem[n_node] * 1000, "mm\n")
cat("  厳密解    :", w_exact_fn(0) * 1000, "mm\n")

# ------------------------------------------------------------
# 7. 可視化
# ------------------------------------------------------------
hermite_w <- function(xi, Le, w1, th1, w2, th2) {
  N1 <- 1 - 3 * xi^2 + 2 * xi^3
  N2 <- Le * (xi - 2 * xi^2 + xi^3)
  N3 <- 3 * xi^2 - 2 * xi^3
  N4 <- Le * (-xi^2 + xi^3)
  N1 * w1 + N2 * th1 + N3 * w2 + N4 * th2
}

fem_curve <- do.call(rbind, lapply(seq_len(n_elem), function(e) {
  xi_seq <- seq(0, 1, length.out = 20)
  w1v <- w_fem[e]
  th1v <- th_fem[e]
  w2v <- w_fem[e + 1]
  th2v <- th_fem[e + 1]
  s_local <- s_nodes[e] + xi_seq * Le
  data.frame(x = l - s_local, w_mm = hermite_w(xi_seq, Le, w1v, th1v, w2v, th2v) * 1000)
}))

x_fine <- seq(0, l, length.out = 300)
exact_curve <- data.frame(x = x_fine, w_mm = w_exact_fn(x_fine) * 1000)

p1 <- ggplot() +
  geom_line(data = exact_curve, aes(x = x, y = w_mm, color = "厳密解"), linewidth = 1.2) +
  geom_line(
    data = fem_curve, aes(x = x, y = w_mm, color = "FEM(要素内補間)"),
    linetype = "dashed", linewidth = 0.8
  ) +
  geom_point(
    data = data.frame(x = x_nodes, w_mm = w_fem * 1000),
    aes(x = x, y = w_mm, color = "FEM(節点)"), size = 2
  ) +
  geom_vline(xintercept = c(a, a + b), linetype = "dotted", color = "gray50") +
  scale_color_manual(values = c(
    "厳密解" = "gray40", "FEM(要素内補間)" = "steelblue",
    "FEM(節点)" = "firebrick"
  ), name = "") +
  labs(
    title = "中間区間の逆三角形分布荷重を受ける片持ち梁:FEM vs 厳密解",
    subtitle = paste0("要素数 = ", n_elem, "(荷重区間の境界にちょうど節点があり完全一致)"),
    x = "自由端からの距離 x [m]", y = "たわみ量 w [mm]"
  ) +
  theme_minimal(base_size = 12)

print(p1)
   自由端起点_x_m FEM近似解_mm  厳密解_mm         差_mm
1             2.0   0.00000000 0.00000000  0.000000e+00
2             1.9   0.00178284 0.00178284  4.451734e-16
3             1.8   0.00694852 0.00694852  2.235191e-15
4             1.7   0.01522274 0.01522274  6.000409e-15
5             1.6   0.02633122 0.02633122  8.219120e-15
6             1.5   0.03999968 0.03999968  5.245804e-15
7             1.4   0.05595384 0.05595384 -2.289835e-15
8             1.3   0.07391941 0.07391941 -1.390554e-14
9             1.2   0.09362211 0.09362211 -2.882417e-14
10            1.1   0.11478772 0.11478772 -4.653222e-14
11            1.0   0.13714405 0.13714405 -6.747380e-14
12            0.9   0.16042750 0.16042750 -9.175993e-14
13            0.8   0.18439167 0.18439167 -1.189326e-13
14            0.7   0.20881583 0.20881583 -1.487699e-13
15            0.6   0.23351356 0.23351356 -1.813549e-13
16            0.5   0.25834129 0.25834129 -2.162159e-13
17            0.4   0.28320688 0.28320688 -2.529088e-13
18            0.3   0.30807525 0.30807525 -2.904899e-13
19            0.2   0.33294362 0.33294362 -3.280709e-13
20            0.1   0.35781199 0.35781199 -3.650968e-13
21            0.0   0.38268037 0.38268037 -4.017897e-13

自由端でのたわみ量:
  FEM近似解: 0.3826804 mm
  厳密解    : 0.3826804 mm
Figure 2

厳密解の公式

  • 出典 : 「構造力学公式集 昭和61年版」(土木学会)

反力・せん断力

\[\begin{eqnarray}R_B &=& \frac{1}{2}p_0b\\M_B &=& -\frac{p_0b}{6}(3c+2b)\\Q_1 &=& 0\\Q_2 &=& -\frac{1}{2}p_0b\left\{\frac{2(x-a)}{b}-\frac{(x-a)^2}{b^2}\right\}\\Q_3 &=& -\frac{1}{2}p_0b\end{eqnarray}\]

曲げモーメント

\[\begin{eqnarray}
M_1 &=& 0\\
M_2 &=& -\frac{p_0}{6b}\left\{3b(x-a)^2-(x-a)^3\right\}\\
M_3 &=& -\frac{1}{6}p_0b(3x-3a-b)\\
M_{\max} &=& -\frac{1}{6}p_0b(3c+2b), \quad [x=l]
\end{eqnarray}\]

たわみ

\[\begin{eqnarray}
w_1 &=& \frac{p_0b}{120EI}\Big\{20c^3+50c^2b+40cb^2+11b^3\\
&&+5(6c^2+8cb+3b^2)(a-x)\Big\}\\
w_2 &=& \frac{p_0b}{120EI}\Big\{20c^3+20c^2b-4b^3\\
&&{\color{gray}{+}}5(6c^2+8cb+3b^2)(a+b-x)\\
&&+\frac{5}{b}(x-a)^4-\frac{1}{b^2}(x-a)^5\Big\}\\
w_3 &=& \frac{p_0b}{12EI}\left\{(3c+2b)(l-x)^2-(l-x)^3\right\}\\
w_{\max} &=& \frac{p_0b}{120EI}\Big\{20c^3+50bc^2+40b^2c+11b^3\\
&&+5(6c^2+8cb+3b^2)a\Big\}, \quad [x=0]
\end{eqnarray}\]

たわみ角

\[\begin{eqnarray}
\theta_1 &=& \frac{p_0b}{24EI}(6c^2+8cb+3b^2)\\
\theta_2 &=& \frac{p_0b}{24EI}\left\{6c^2+8cb+3b^2-\frac{4}{b}(x-a)^3+\frac{1}{b^2}(x-a)^4\right\}\\
\theta_3 &=& \frac{p_0b}{12EI}\left\{2(3c+2b)(l-x)-3(l-x)^2\right\}\\
\theta_A &=& \frac{p_0b}{24EI}(6c^2+8cb+3b^2)
\end{eqnarray}\]

以上です。