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

片持ち梁-自由端で最大の三角形状分布荷重
片持ち梁のたわみ:FEM(オイラー・ベルヌーイ梁要素) vs 厳密解
# ============================================================
# 片持ち梁のたわみ(自由端で最大の三角形分布荷重):FEM vs 厳密解
# ============================================================
#
# 厳密解(xは自由端Aから測った距離):
# w(x) = (p0 l^4)/(120EI) * { 11 - 15(x/l) + 5(x/l)^4 - (x/l)^5 }
# w_max = (11 p0 l^4)/(120EI) [x = 0, 自由端]
# θ(x) = (p0 l^3)/(24EI) * { 3 - 4(x/l)^3 + (x/l)^4 }
# θ_A = (p0 l^3)/(8EI) [x = 0, 自由端]
#
# s : FEM座標(固定端起点、s=0で固定端、s=lで自由端)
# x : 厳密解の座標(自由端起点、x = l - s)
#
# 荷重は反力R_B・固定端モーメントM_Bの式と整合するように
# q(x) = p0 * (1 - x/l) [xは自由端起点]
# であることを確認済み。FEM座標sに変換すると
# q(s) = p0 * (s/l) [s=0(固定端)でゼロ、s=l(自由端)でp0]
library(ggplot2)
# ------------------------------------------------------------
# 1. 梁の諸元と荷重の設定
# ------------------------------------------------------------
l <- 2.0
p0 <- 800
E <- 210e9
I <- 4.1667e-6
EI <- E * I
# FEM座標s(固定端起点)での分布荷重。s=0でゼロ、s=lでp0となる直線。
q_dist <- function(s) p0 * (s / l)
# ------------------------------------------------------------
# 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. 等価節点荷重をガウス求積で数値的に計算する
# ------------------------------------------------------------
gauss_pts <- c(
-sqrt((3 - 2 * sqrt(6 / 5)) / 7), -sqrt((3 + 2 * sqrt(6 / 5)) / 7),
sqrt((3 - 2 * sqrt(6 / 5)) / 7), sqrt((3 + 2 * sqrt(6 / 5)) / 7)
)
gauss_wts <- c(
(18 + sqrt(30)) / 36, (18 - sqrt(30)) / 36,
(18 + sqrt(30)) / 36, (18 - sqrt(30)) / 36
)
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 <- 8L
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) (p0 * l^4) / (120 * EI) * (11 - 15 * (x / l) + 5 * (x / l)^4 - (x / l)^5)
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(" 厳密解 :", 11 * p0 * l^4 / (120 * EI) * 1000, "mm (公式: w_max = 11 p0 l^4 / 120EI)\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)
w1 <- w_fem[e]
th1 <- th_fem[e]
w2 <- w_fem[e + 1]
th2 <- 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, w1, th1, w2, th2) * 1000)
}))
fem_curve$w_exact_mm <- w_exact_fn(fem_curve$x) * 1000
fem_curve$diff_nm <- (fem_curve$w_mm - fem_curve$w_exact_mm) * 1e6 # ナノメートル単位
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
) +
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)
p2 <- ggplot(fem_curve, aes(x = x, y = diff_nm)) +
geom_line(color = "darkred") +
geom_hline(yintercept = 0, linetype = "dotted") +
labs(
title = "要素内部での誤差(FEM補間 - 厳密解)",
subtitle = "荷重が大きい自由端側(x小)で誤差も大きくなる",
x = "自由端からの距離 x [m]", y = "差 [nm]"
) +
theme_minimal(base_size = 12)
print(p1)
print(p2) 自由端起点_x_m FEM近似解_mm 厳密解_mm 差_mm
1 2.00 0.00000000 0.00000000 0.000000e+00
2 1.75 0.03571772 0.03571772 6.890322e-15
3 1.50 0.13345131 0.13345131 2.656209e-14
4 1.25 0.27947321 0.27947321 5.706546e-14
5 1.00 0.46094869 0.46094869 9.470202e-14
6 0.75 0.66638232 0.66638232 1.367795e-13
7 0.50 0.88606434 0.88606434 1.824096e-13
8 0.25 1.11251714 1.11251714 2.302603e-13
9 0.00 1.34094165 1.34094165 2.791101e-13
自由端でのたわみ量:
FEM近似解: 1.340942 mm
厳密解 : 1.340942 mm (公式: w_max = 11 p0 l^4 / 120EI)厳密解の公式
- 出典 : 「構造力学公式集 昭和61年版」(土木学会)
反力・せん断力
\[\begin{eqnarray}R_B &=& \frac{p_0 l}{2}\\M_B &=& -\frac{p_0 l^2}{3}\\Q &=& -\frac{p_0 l}{2}\left\{2\cdot\frac{x}{l} - \left(\frac{x}{l}\right)^2\right\}\end{eqnarray}\]
曲げモーメント
\[\begin{eqnarray}
M &=& -\frac{p_0 l^2}{6}\left\{3\left(\frac{x}{l}\right)^2 - \left(\frac{x}{l}\right)^3\right\}\\
M_{\max} &=& -\frac{p_0 l^2}{3}, \quad [x = l]
\end{eqnarray}\]
たわみ
\[\begin{eqnarray}
w &=& \frac{p_0 l^4}{120 EI}\left\{11 - 15\frac{x}{l} + 5\left(\frac{x}{l}\right)^4 - \left(\frac{x}{l}\right)^5\right\}
\\w_{\max} &=& \frac{11\, p_0 l^4}{120\, EI}, \quad [x = 0]
\end{eqnarray}\]
たわみ角
\[\begin{eqnarray}
\theta &=& \frac{p_0 l^3}{24 EI}\left\{3 - 4\left(\frac{x}{l}\right)^3 + \left(\frac{x}{l}\right)^4\right\}\\
\theta_A &=& \frac{p_0 l^3}{8 EI}
\end{eqnarray}\]
以上です。



