云计算百科
云计算领域专业知识百科平台

【零基础学智能仿真-40】随机有限元入门——材料不确定性如何影响位移预测

课程摘要

上一节讨论了网格划分带来的数值误差,本节把目光转向材料本身的不确定性。我们以两单元拉杆为例,让两个单元的弹性模量随机变化,重复进行有限元求解,观察端部位移的分布,并估计位移超过指定限值的概率。课程同时介绍空间相关性、对数正态分布、Monte Carlo 统计误差,以及随机场向复杂有限元模型扩展的思路。

一、从“一个答案”到“一组可能的答案”

此前,我们给拉杆指定弹性模量 \\(E=210000\\ \\mathrm{MPa}\\),计算出唯一的端部位移:

\\[ u_3=\\frac{FL}{EA}=0.476190\\ \\mathrm{mm} \\]

但真实材料不可能处处完全相同。即使是同一根杆,不同位置的弹性模量也可能略有差异。

于是,问题变成:

如果材料参数存在波动,端部位移通常是多少?它有多大可能超过允许值?

这正是随机有限元要回答的问题之一。它不是让有限元求解器“随机地求解”,而是为不确定的输入建立概率模型,再研究输出如何变化。

上一节的网格误差与本节的材料不确定性也不要混为一谈:前者来自计算近似,后者来自我们对物理对象的描述。

二、建立一个看得清楚的随机有限元模型

继续使用课程中的两单元一维拉杆:

  • 杆长:\\(L=1000\\ \\mathrm{mm}\\)
  • 截面积:\\(A=100\\ \\mathrm{mm^2}\\)
  • 右端拉力:\\(F=10000\\ \\mathrm N\\)
  • 左端固定
  • 两个单元等长:\\(L_e=500\\ \\mathrm{mm}\\)

这次不要求两个单元的弹性模量完全相同,而是分别记为 \\(E_1\\) 和 \\(E_2\\):

固定端 单元 1 单元 2 拉力
u₁=0 ───────── E₁ ─────────●──────── E₂ ─────────→ F
节点 2 节点 3

对于某一组确定的 \\(E_1,E_2\\),单元刚度仍按熟悉的公式计算:

\\[ k_1=\\frac{E_1A}{L_e},\\qquad k_2=\\frac{E_2A}{L_e} \\]

固定节点 1 后,待求位移为 \\(u_2,u_3\\),对应的有限元方程是:

\\[ \\begin{bmatrix} k_1+k_2 & -k_2\\\\ -k_2 & k_2 \\end{bmatrix} \\begin{bmatrix} u_2\\\\u_3 \\end{bmatrix} = \\begin{bmatrix} 0\\\\F \\end{bmatrix} \\]

这个小模型还有一个特别有用的解析结果:

\\[ u_2=\\frac{FL_e}{AE_1},\\qquad u_3=\\frac{FL_e}{A} \\left(\\frac{1}{E_1}+\\frac{1}{E_2}\\right) \\]

因此,我们既能练习“随机输入—有限元求解—统计输出”,又能用解析式逐次检查程序有没有算错。

例如,若 \\(E_1=210000\\ \\mathrm{MPa}\\)、\\(E_2=189000\\ \\mathrm{MPa}\\),则:

\\[ u_3= \\frac{10000\\times500}{100} \\left(\\frac{1}{210000}+\\frac{1}{189000}\\right) \\approx0.502646\\ \\mathrm{mm} \\]

第二个单元变软后,端部位移比名义值 \\(0.476190\\ \\mathrm{mm}\\) 增大了。

三、怎样描述材料的随机性?

本节作三个明确的教学假设:

  • 两个单元的弹性模量平均值均为 \\(210000\\ \\mathrm{MPa}\\)。
  • 两者的变异系数均为 \\(10\\%\\)。变异系数是“标准差÷平均值”。
  • 两个位置的材料性质具有正相关性:一处偏硬时,邻近一处也更可能偏硬。
  • 弹性模量必须为正,因此示例采用对数正态分布。需要留意:对数正态分布参数对应的是 \\(\\ln E\\) 的正态分布,而不是直接把 \\(E\\) 当作正态变量。SciPy 对数正态分布文档

    设弹性模量的目标平均值为 \\(\\bar E\\)、变异系数为 \\(c_v\\),代码中使用:

    \\[ \\sigma_{\\ln E}=\\sqrt{\\ln(1+c_v^2)},\\qquad \\mu_{\\ln E}=\\ln\\bar E-\\frac{\\sigma_{\\ln E}^2}{2} \\]

    然后由标准正态变量 \\(Z\\) 生成:

    \\[ E=\\exp\\!\\left(\\mu_{\\ln E}+\\sigma_{\\ln E}Z\\right) \\]

    代码中的 rho = 0.60 用来控制两个对数弹性模量所对应的正态变量的相关性;它不严格等于变换后 \\(E_1,E_2\\) 的相关系数。对入门实验,先分清这一点即可。

    四、完整可运行代码

    运行环境只需 NumPy 和 Matplotlib。将下面代码保存为 lesson40_random_bar.py,在选定的 Python 环境中运行:

    """第四十节:两单元随机杆的非侵入式 Monte Carlo 有限元。"""

    from pathlib import Path

    import matplotlib

    matplotlib.use("Agg")
    import matplotlib.pyplot as plt
    import numpy as np

    # N、mm、MPa 单位制:1 MPa = 1 N/mm²
    length, area, force = 1000.0, 100.0, 10000.0
    e_mean, cv, rho = 210000.0, 0.10, 0.60
    n_samples, limit = 10000, 0.55
    element_length = length / 2

    # 先生成相关标准正态变量,再变换为始终为正的弹性模量。
    rng = np.random.default_rng(2026)
    z = rng.standard_normal((n_samples, 2))
    z[:, 1] = rho * z[:, 0] + np.sqrt(1 – rho**2) * z[:, 1]
    sigma_log = np.sqrt(np.log1p(cv**2))
    mu_log = np.log(e_mean) – 0.5 * sigma_log**2
    moduli = np.exp(mu_log + sigma_log * z)

    # 节点 1 固定,只求解节点 2、3 的位移。
    tip_displacements = np.empty(n_samples)
    for i, (e1, e2) in enumerate(moduli):
    k1, k2 = e1 * area / element_length, e2 * area / element_length
    k_free = np.array([[k1 + k2, -k2], [-k2, k2]])
    u_free = np.linalg.solve(k_free, np.array([0.0, force]))
    tip_displacements[i] = u_free[1]

    # 每次有限元求解都应与串联杆的解析表达式一致。
    exact = force * element_length / area * (
    1 / moduli[:, 0] + 1 / moduli[:, 1]
    )
    np.testing.assert_allclose(
    tip_displacements, exact, rtol=1e-12, atol=1e-12
    )

    nominal = force * length / (area * e_mean)
    sample_mean = tip_displacements.mean()
    sample_sd = tip_displacements.std(ddof=1)
    q025, q975 = np.quantile(tip_displacements, [0.025, 0.975])
    p_exceed = np.mean(tip_displacements > limit)
    mc_se = np.sqrt(p_exceed * (1 – p_exceed) / n_samples)
    theoretical_mean = nominal * (1 + cv**2)

    print(f"样本数: {n_samples}")
    print(f"确定性名义位移: {nominal:.6f} mm")
    print(f"Monte Carlo 平均位移: {sample_mean:.6f} mm")
    print(f"理论总体平均位移: {theoretical_mean:.6f} mm")
    print(f"位移样本标准差: {sample_sd:.6f} mm")
    print(f"位移 2.5%~97.5% 分位区间: [{q025:.6f}, {q975:.6f}] mm")
    print(f"P(位移 > {limit:.2f} mm) 估计: {p_exceed:.4%}")
    print(f"上述概率估计的 Monte Carlo 标准误: {mc_se:.4%}")
    print("检查通过:每个样本的有限元位移与解析式一致。")

    fig, ax = plt.subplots(figsize=(9, 5.2), dpi=160)
    ax.hist(tip_displacements, bins=55, color="#257d9c", alpha=0.86)
    ax.axvline(
    nominal, color="#183b56", linestyle="–", linewidth=2,
    label=f"Nominal: {nominal:.3f} mm",
    )
    ax.axvline(
    sample_mean, color="#36a386", linewidth=2,
    label=f"Sample mean: {sample_mean:.3f} mm",
    )
    ax.axvline(
    limit, color="#d56b32", linewidth=2,
    label=f"Illustrative limit: {limit:.2f} mm",
    )
    ax.set(
    xlabel="Tip displacement (mm)",
    ylabel="Number of samples",
    title="Monte Carlo FEM: uncertain modulus, uncertain displacement",
    )
    ax.grid(axis="y", alpha=0.18)
    ax.legend(frameon=False)
    fig.tight_layout()

    output = Path(__file__).with_name("lesson40_displacement_distribution.png")
    fig.savefig(output)
    plt.close(fig)
    print(f"图片已保存: {output}")

    预期输出

    以下是上述代码实际运行得到的结果。使用不同的 NumPy 版本时,随机样本的末几位统计值可能略有差别:

    样本数: 10000
    确定性名义位移: 0.476190 mm
    Monte Carlo 平均位移: 0.480983 mm
    理论总体平均位移: 0.480952 mm
    位移样本标准差: 0.042945 mm
    位移 2.5%~97.5% 分位区间: [0.403046, 0.569974] mm
    P(位移 > 0.55 mm) 估计: 6.1900%
    上述概率估计的 Monte Carlo 标准误: 0.2410%
    检查通过:每个样本的有限元位移与解析式一致。
    图片已保存: …/lesson40_displacement_distribution.png

    程序生成的实际数据图如下;橙线右侧是超过示例位移限值的样本:

    五、读懂结果,而不只是读出数字

    第一,为什么平均位移比“平均弹性模量算出的位移”大?

    名义位移是 \\(0.476190\\ \\mathrm{mm}\\),随机样本平均位移约为 \\(0.480983\\ \\mathrm{mm}\\)。原因藏在 \\(u_3\\) 与 \\(1/E\\) 的关系里:材料变软时增加的位移,不能简单地被同幅度“变硬”造成的位移减少抵消。

    对于本例的对数正态分布,还可推得理论总体平均值:

    \\[ \\mathbb E[u_3] = \\frac{FL}{A\\bar E}(1+c_v^2) = 0.480952\\ \\mathrm{mm} \\]

    它与样本平均值接近,是对随机采样和统计代码的第二重检查。

    第二,区间和“标准误”回答的是不同问题。

    \\([0.403046,\\ 0.569974]\\ \\mathrm{mm}\\) 是模拟位移的 2.5%~97.5% 分位区间,描述在既定材料概率模型下,不同材料样本可能产生怎样的位移。它不是“平均位移的95%置信区间”。

    0.2410% 则是超限概率估计的 Monte Carlo 标准误,描述只抽取 10000 次时,所报 6.19% 有多大的抽样波动。这里的 0.2410% 应读作约 0.241 个百分点。

    第三,不能把示例限值当作工程判据。

    \\(0.55\\ \\mathrm{mm}\\) 是为了练习概率计算而设定的演示限值。实际工程的允许位移必须由具体结构、功能要求和适用规范确定。6.19% 也只在本节假定的材料分布、变异系数及相关性成立时才有意义。

    还有一个容易忽略的现象:在这个等截面、右端给定拉力的一维杆中,两单元的轴向应力均为 \\(F/A=100\\ \\mathrm{MPa}\\)。随机弹性模量改变的是应变和位移,不会使本例的轴向应力也随机变化。换成位移控制、变截面或更复杂的结构后,情况可能不同。

    六、从两个随机数走向随机场

    本节实际上把材料划成两段:每段使用一个随机弹性模量。这是一个很粗的、分段常数的空间随机模型。真实材料可能沿位置 \\(x\\) 连续变化,此时要描述 \\(E(x,\\omega)\\),还要回答“相距多远的两处材料性质仍然相似”——这便涉及空间相关长度。

    一种常见的随机场表示方法是 Karhunen–Loève(KL)展开。例如,为保持弹性模量为正,可以先表示其对数场:

    \\[ \\ln E(x,\\omega) \\approx m(x)+ \\sum_{j=1}^{M} \\sqrt{\\lambda_j}\\,\\phi_j(x)\\,\\xi_j(\\omega) \\]

    其中,\\(\\phi_j(x)\\) 描述空间变化模式,\\(\\lambda_j\\) 表示相应模式的权重,\\(\\xi_j\\) 是随机系数。保留有限项后,就能用有限个随机变量近似连续随机场。本节代码尚未实现 KL 展开;两个单元各取一个模量,是帮助我们先掌握整个计算链条的起点。随机介质有限元与 KL 展开的原始研究

    七、本节练习

  • 把 cv 改为 0。你预计直方图会变成什么样?端部位移应回到多少?
  • 保持其他参数不变,把 rho 改为 0。比较两次位移标准差,思考:两个单元“同时偏软”的机会改变了吗?
  • 将 n_samples 依次设为 1000、10000、50000。观察超限概率估计和 Monte Carlo 标准误如何变化。样本更多会减小抽样误差,但不会自动修正错误的材料概率模型。
  • 本节完成了“随机材料参数 → 重复有限元求解 → 位移分布 → 超限概率”的最小闭环。接下来可以把这种方法移植到二维或三维网格:先为各区域生成具有空间相关性的材料场,再对每个样本调用有限元求解器。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 【零基础学智能仿真-40】随机有限元入门——材料不确定性如何影响位移预测
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!