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

片持ち梁-中間区間の三角形状分布荷重
片持ち梁のたわみ:FEM(オイラー・ベルヌーイ梁要素) vs 厳密解
ガウス求積の評価点の個数 \(\,n\)、位置 \(\xi_i\) そして重み \(w_i\)につきましては、https://pomax.github.io/bezierinfo/legendre-gauss.html から引用しています。
# ============================================================
# 片持ち梁のたわみ(中間区間の三角形分布荷重):FEM vs 厳密解
# ============================================================
#
# 厳密解(xは自由端Aから測った距離。区間ごとに式が異なる):
# w1 = (p0b/120EI){5(6c^2+4bc+b^2)(a-x) + 4(5c^3+10bc^2+5b^2c+b^3)} [0<=x<=a]
# w2 = (p0b/120EI){20c^3+10bc^2-b^3-5(6c^2+4bc+b^2)(x-a-b)+(1/b^2)(x-a)^5} [a<=x<=a+b]
# w3 = (p0b/12EI){(b+3c)(l-x)^2-(l-x)^3} [a+b<=x<=l]
# w_max = (p0b/120EI){5a(6c^2+4bc+b^2)+4(5c^3+10bc^2+5b^2c+b^3)} [x=0, 自由端]
#
# s : FEM座標(固定端起点、s=0で固定端、s=lで自由端)
# x : 厳密解の座標(自由端起点、x = l - s)
#
# 荷重をxの関数として定義し(区間外は0、区間内はaからa+bまで
# 直線的に0からp0まで増加)、ガウス求積による等価節点荷重の計算に渡す。
library(ggplot2)
# ------------------------------------------------------------
# 1. 梁の諸元と荷重の設定
# ------------------------------------------------------------
l <- 2.0
a <- 0.4
b <- 0.8
c <- l - a - b
p0 <- 600 # 荷重区間の右端(x=a+b)での最大強度 [N/m]
E <- 210e9
I <- 4.1667e-6
EI <- E * I
# 分布荷重をxの関数として定義(自由端起点)。区間[a,a+b]で0からp0まで直線的に増加。
q_of_x <- function(x) {
ifelse(x < a | x > a + b, 0, p0 * (x - a) / b)
}
# FEM座標s(固定端起点)の関数に変換(x = l - s)
q_dist <- function(s) q_of_x(l - 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点ガウス求積)
# ------------------------------------------------------------
# 三角形荷重は要素内で最大4次の項(形状関数の3次×荷重の1次)になるため、
# 余裕を持って6点ガウス求積(11次まで厳密)を使う。
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) * (5 * (6 * c^2 + 4 * b * c + b^2) * (a - x) + 4 * (5 * c^3 + 10 * b * c^2 + 5 * b^2 * c + b^3)),
ifelse(
x <= a + b,
(p0 * b) / (120 * EI) * (20 * c^3 + 10 * b * c^2 - b^3 - 5 * (6 * c^2 + 4 * b * c + b^2) * (x - a - b) + (1 / b^2) * (x - a)^5),
(p0 * b) / (12 * EI) * ((b + 3 * c) * 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.00141713 0.00141713 1.266348e-16
3 1.8 0.00548567 0.00548567 6.800116e-16
4 1.7 0.01193133 0.01193133 1.868297e-15
5 1.6 0.02047984 0.02047984 2.362693e-15
6 1.5 0.03085690 0.03085690 7.875645e-16
7 1.4 0.04278823 0.04278823 -2.713108e-15
8 1.3 0.05599955 0.05599955 -8.083811e-15
9 1.2 0.07021658 0.07021658 -1.532108e-14
10 1.1 0.08516782 0.08516782 -2.475797e-14
11 1.0 0.10061405 0.10061405 -3.691492e-14
12 0.9 0.11637314 0.11637314 -5.176415e-14
13 0.8 0.13231437 0.13231437 -6.891709e-14
14 0.7 0.14834988 0.14834988 -8.801293e-14
15 0.6 0.16442611 0.16442611 -1.090794e-13
16 0.5 0.18051520 0.18051520 -1.317280e-13
17 0.4 0.19660643 0.19660643 -1.556255e-13
18 0.3 0.21269773 0.21269773 -1.801059e-13
19 0.2 0.22878903 0.22878903 -2.046141e-13
20 0.1 0.24488033 0.24488033 -2.287615e-13
21 0.0 0.26097163 0.26097163 -2.526868e-13
自由端でのたわみ量:
FEM近似解: 0.2609716 mm
厳密解 : 0.2609716 mm厳密解の公式
- 出典 : 「構造力学公式集 昭和61年版」(土木学会)
反力・せん断力
\[\begin{eqnarray}R_B &=& \frac{1}{2}p_0b\\M_B &=& -\frac{1}{2}p_0b\left(\frac{b}{3}+c\right)\\Q_1 &=& 0\\Q_2 &=& -\frac{1}{2}p_0b\frac{(x-a)^2}{b^2}\\Q_3 &=& -\frac{1}{2}p_0b\end{eqnarray}\]
曲げモーメント
\[\begin{eqnarray}
M_1 &=& 0\\
M_2 &=& -\frac{p_0}{6b}(x-a)^3\\
M_3 &=& -\frac{1}{6}p_0b(3x-3a-2b)\\
M_{\max} &=& -\frac{1}{6}p_0b(b+3c), \quad [x=l]
\end{eqnarray}\]
たわみ
\[\begin{eqnarray}
w_1 &=& \frac{p_0b}{120EI}\Big\{5(6c^2+4bc+b^2)(a-x)\\
&&+4(5c^3+10bc^2+5b^2c+b^3)\Big\}\\
w_2 &=& \frac{p_0b}{120EI}\Big\{20c^3+10bc^2-b^3-5(6c^2+4bc+b^2)(x-a-b)\\
&&+\frac{1}{b^2}(x-a)^5\Big\}\\
w_3 &=& \frac{p_0b}{12EI}\left\{(b+3c)(l-x)^2-(l-x)^3\right\}\\
w_{\max} &=& \frac{p_0b}{120EI}\Big\{5a(6c^2+4bc+b^2)+4(5c^3+10bc^2+5b^2c+b^3)\Big\}, \quad [x=0]
\end{eqnarray}\]
たわみ角
\[\begin{eqnarray}
\theta_1 &=& \frac{p_0b}{24EI}(6c^2+4bc+b^2)\\
\theta_2 &=& -\frac{p_0b}{24EI}\left\{\frac{1}{b^2}(x-a)^4-(6c^2+4bc+b^2)\right\}\\
\theta_3 &=& -\frac{p_0b}{12EI}\left\{3(l-x)^2-2(b+3c)(l-x)\right\}\\
\theta_A &=& \frac{p_0b}{24EI}(6c^2+4bc+b^2)
\end{eqnarray}\]
以上です。


