=== "模型训练命令"
``` sh
# linux
wget https://paddle-org.bj.bcebos.com/paddlescience/datasets/bracket/bracket_dataset.tar
# windows
# curl https://paddle-org.bj.bcebos.com/paddlescience/datasets/bracket/bracket_dataset.tar --output bracket_dataset.tar
# unzip it
tar -xvf bracket_dataset.tar
python bracket.py
```
=== "模型评估命令"
``` sh
# linux
wget https://paddle-org.bj.bcebos.com/paddlescience/datasets/bracket/bracket_dataset.tar
# windows
# curl https://paddle-org.bj.bcebos.com/paddlescience/datasets/bracket/bracket_dataset.tar --output bracket_dataset.tar
# unzip it
tar -xvf bracket_dataset.tar
python bracket.py mode=eval EVAL.pretrained_model_path=https://paddle-org.bj.bcebos.com/paddlescience/models/bracket/bracket_pretrained.pdparams
```
预训练模型 | 指标 |
---|---|
bracket_pretrained.pdparams | loss(commercial_ref_u_v_w_sigmas): 32.28704 MSE.u(commercial_ref_u_v_w_sigmas): 0.00005 MSE.v(commercial_ref_u_v_w_sigmas): 0.00000 MSE.w(commercial_ref_u_v_w_sigmas): 0.00734 MSE.sigma_xx(commercial_ref_u_v_w_sigmas): 27.64751 MSE.sigma_yy(commercial_ref_u_v_w_sigmas): 1.23101 MSE.sigma_zz(commercial_ref_u_v_w_sigmas): 0.89106 MSE.sigma_xy(commercial_ref_u_v_w_sigmas): 0.84370 MSE.sigma_xz(commercial_ref_u_v_w_sigmas): 1.42126 MSE.sigma_yz(commercial_ref_u_v_w_sigmas): 0.24510 |
线弹性方程在形变分析中起着核心的作用。在物理和工程领域,形变分析是研究物体在外力作用下的形状和尺寸变化的方法。线弹性方程是描述物体在受力后恢复原状的能力的数学模型。具体来说,线弹性方程通常是指应力和应变之间的关系。应力是一个物理量,用于描述物体内部由于外力而产生的单位面积上的力。应变则描述了物体的形状和尺寸的变化。线弹性方程通常可以表示为应力和应变之间的线性关系,即应力和应变是成比例的。这种关系可以用一个线性方程来表示,其中系数被称为弹性模量(或杨氏模量)。这种模型假设物体在受力后能够完全恢复原状,即没有永久变形。这种假设在许多情况下是合理的,例如在研究金属的力学行为时。然而,对于某些材料(如塑料或橡胶),这种假设可能不准确,因为它们在受力后可能会产生永久变形。线弹性方程只是形变分析中的一部分。要全面理解形变,还需要考虑其他因素,例如物体的初始形状和尺寸、外力的历史、材料的其他物理性质(如热膨胀系数和密度)等。然而,线弹性方程提供了一个基本的框架,用于描述和理解物体在受力后的行为。
本案例主要研究如下金属连接件在给定载荷下的形变情况,并使用深度学习方法根据线弹性等方程进行求解,连接件如下所示(参考 Matlab deflection-analysis-of-a-bracket)。
![bracket](https://paddle-org.bj.bcebos.com/paddlescience/docs/Bracket/stl.png){ loading=lazy } Bracket 金属件载荷示意图,红色区域表示载荷面上述连接件包括一个垂直于 x 轴的背板和与之连接的垂直于 z 轴的带孔平板。其中背板处于固定状态,带孔平板的最右侧表面(红色区域)受到 z 轴负方向,单位面积大小为
--8<--
examples/bracket/bracket.py:29:38
--8<--
接下来开始讲解如何将问题一步一步地转化为 PaddleScience 代码,用深度学习的方法求解该问题。 为了快速理解 PaddleScience,接下来仅对模型构建、方程构建、计算域构建等关键步骤进行阐述,而其余细节请参考 API文档。
在 bracket 问题中,每一个已知的坐标点
这里考虑到两组物理量对应着不同的方程,因此使用两个模型来分别预测这两组物理量:
上式中 disp_net
,$g$ 为应力模型 stress_net
,用 PaddleScience 代码表示如下:
--8<--
examples/bracket/bracket.py:23:27
--8<--
为了在计算时,准确快速地访问具体变量的值,在这里指定应变模型的输入变量名是 ("x", "y", "z")
,输出变量名是 ("u", "v", "w")
,这些命名与后续代码保持一致(应力模型同理)。
接着通过指定 MLP 的层数、神经元个数,就实例化出了一个拥有 6 层隐藏神经元,每层神经元数为 512 的神经网络模型 disp_net
,使用 silu
作为激活函数,并使用 WeightNorm
权重归一化(应力模型 stress_net
同理)。
Bracket 案例涉及到以下线弹性方程,使用 PaddleScience 内置的 LinearElasticity
即可。
--8<--
examples/bracket/bracket.py:40:45
--8<--
本问题的几何区域由 stl 文件指定,按照下方命令,下载并解压到 bracket/
文件夹下。
注:数据集中的 stl 文件和测试集数据均来自 Bracket - NVIDIA Modulus。
# linux
wget https://paddle-org.bj.bcebos.com/paddlescience/datasets/bracket/bracket_dataset.tar
# windows
# curl https://paddle-org.bj.bcebos.com/paddlescience/datasets/bracket/bracket_dataset.tar --output bracket_dataset.tar
# unzip it
tar -xvf bracket_dataset.tar
解压完毕之后,bracket/stl
文件夹下即存放了计算域构建所需的 stl 几何文件。
???+ warning "注意"
**使用 `Mesh` 类之前,必须先按照[1.4.3 额外依赖安装[可选]](https://paddlescience-docs.readthedocs.io/zh/latest/zh/install_setup/#143)文档,安装好 open3d、pysdf、PyMesh 3 个几何依赖包。**
然后通过 PaddleScience 内置的 STL 几何类 Mesh
来读取、解析这些几何文件,并且通过布尔运算,组合出各个计算域,代码如下:
--8<--
examples/bracket/bracket.py:47:59
--8<--
本案例共涉及到 5 个约束,在具体约束构建之前,可以先构建数据读取配置,以便后续构建多个约束时复用该配置。
--8<--
examples/bracket/bracket.py:61:71
--8<--
以作用在背板内部点的 InteriorConstraint
为例,代码如下:
--8<--
examples/bracket/bracket.py:114:150
--8<--
InteriorConstraint
的第一个参数是方程(组)表达式,用于描述如何计算约束目标,此处填入在 3.2 方程构建 章节中实例化好的 equation["LinearElasticity"].equations
;
第二个参数是约束变量的目标值,在本问题中希望与 LinearElasticity 方程相关的 9 个值 equilibrium_x
, equilibrium_y
, equilibrium_z
, stress_disp_xx
, stress_disp_yy
, stress_disp_zz
, stress_disp_xy
, stress_disp_xz
, stress_disp_yz
均被优化至 0;
第三个参数是约束方程作用的计算域,此处填入在 3.3 计算域构建 章节实例化好的 geom["geo"]
即可;
第四个参数是在计算域上的采样配置,此处设置 batch_size
为 2048
。
第五个参数是损失函数,此处选用常用的 MSE 函数,且 reduction
设置为 "sum"
,即会将参与计算的所有数据点产生的损失项求和;
第六个参数是几何点筛选,由于这个约束只施加在背板区域,因此需要对 geo 上采样出的点进行筛选,此处传入一个 lambda 筛选函数即可,其接受点集构成的张量 x, y, z
,返回布尔值张亮,表示每个点是否符合筛选条件,不符合为 False
,符合为 True
;
第七个参数是每个点参与损失计算时的权重,此处我们使用 "sdf"
表示使用每个点到边界的最短距离(符号距离函数值)来作为权重,这种 sdf 加权的方法可以加大远离边界(难样本)点的权重,减少靠近边界的(简单样本)点的权重,有利于提升模型的精度和收敛速度。
第八个参数是约束条件的名字,需要给每一个约束条件命名,方便后续对其索引。此处命名为 "support_interior" 即可。
另一个作用在带孔平板上的约束条件则与之类似,代码如下:
--8<--
examples/bracket/bracket.py:151:187
--8<--
对于背板后表面,由于被固定,所以其上的点在三个方向的形变均为 0,因此有如下的边界约束条件:
--8<--
examples/bracket/bracket.py:84:93
--8<--
对于带孔平板右侧长方形载荷面,其上的每个点只受 z 正方向的载荷,大小为
--8<--
examples/bracket/bracket.py:94:102
--8<--
对于除背板后面、带孔平板右侧长方形载荷面外的表面,不受任何载荷,即三个方向的内力平衡,合力为 0,有如下边界条件约束:
--8<--
examples/bracket/bracket.py:103:113
--8<--
在方程约束、边界约束构建完毕之后,以刚才的命名为关键字,封装到一个字典中,方便后续访问。
--8<--
examples/bracket/bracket.py:188:195
--8<--
接下来需要在配置文件中指定训练轮数,此处按实验经验,使用 2000 轮训练轮数,每轮进行 1000 步优化。
--8<--
examples/bracket/conf/bracket.yaml:71:74
--8<--
训练过程会调用优化器来更新模型参数,此处选择较为常用的 Adam
优化器,并配合使用机器学习中常用的 ExponentialDecay 学习率调整策略。
--8<--
examples/bracket/bracket.py:197:201
--8<--
在训练过程中通常会按一定轮数间隔,用验证集(测试集)评估当前模型的训练情况,而验证集的数据来自外部 txt 文件,因此首先使用 ppsci.utils.reader
模块从 txt 文件中读取验证点集:
--8<--
examples/bracket/bracket.py:203:264
--8<--
然后将其转换为字典并进行无量纲化和归一化,再将其包装成字典和 eval_dataloader_cfg
(验证集dataloader配置,构造方式与 train_dataloader_cfg
类似)一起传递给 ppsci.validate.SupervisedValidator
构造评估器。
--8<--
examples/bracket/bracket.py:266:311
--8<--
在模型评估时,如果评估结果是可以可视化的数据,可以选择合适的可视化器来对输出结果进行可视化。
本文中的输入数据是评估器构建中准备好的输入字典 input_dict
,输出数据是对应的 9 个预测的物理量,因此只需要将评估的输出数据保存成 vtu格式 文件,最后用可视化软件打开查看即可。代码如下:
--8<--
examples/bracket/bracket.py:313:330
--8<--
完成上述设置之后,只需要将上述实例化的对象按顺序传递给 ppsci.solver.Solver
,然后启动训练、评估、可视化。
--8<--
examples/bracket/bracket.py:332:359
--8<--
--8<--
examples/bracket/bracket.py
--8<--
下面展示了在测试点集上,3 个方向的挠度
可以看到模型预测的结果与 传统算法求解结果基本一致。