当前位置: 首页 > news >正文

8-SOFA_约束、重力与材料模型补充

一、约束

8-constraint.scn

<?xml version="1.0"?> <!-- Adding boundary conditions --> <Node name="root" dt="0.01" gravity="0 0 0"> <Node name="plugins"> <RequiredPlugin name="Sofa.Component.AnimationLoop"/> <RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <RequiredPlugin name="Sofa.Component.IO.Mesh"/> <RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <RequiredPlugin name="Sofa.Component.Mapping.NonLinear"/> <RequiredPlugin name="Sofa.Component.Mass"/> <RequiredPlugin name="Sofa.Component.MechanicalLoad"/> <RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <RequiredPlugin name="Sofa.Component.SolidMechanics.FEM.Elastic"/> <RequiredPlugin name="Sofa.Component.StateContainer"/> <RequiredPlugin name="Sofa.Component.Topology.Container.Dynamic"/> <RequiredPlugin name="Sofa.Component.Visual"/> <RequiredPlugin name="Sofa.GL.Component.Rendering3D"/> </Node> <DefaultAnimationLoop computeBoundingBox="false"/> <VisualStyle displayFlags="showForceFields"/> <!-- 粗体积网格:用于力学计算 --> <MeshGmshLoader name="meshLoaderCoarse" filename="mesh/liver.msh"/> <!-- 细表面网格:用于视觉渲染 --> <MeshOBJLoader name="meshLoaderFine" filename="mesh/liver-smooth.obj"/> <Node name="Liver"> <EulerImplicitSolver/> <CGLinearSolver iterations="200" tolerance="1e-09" threshold="1e-09"/> <TetrahedronSetTopologyContainer name="topo" src="@../meshLoaderCoarse"/> <TetrahedronSetGeometryAlgorithms template="Vec3d" name="GeomAlgo"/> <MechanicalObject template="Vec3d" name="MechanicalModel" showObject="1" showObjectScale="3"/> <TetrahedronFEMForceField name="FEM" youngModulus="1000" poissonRatio="0.4" method="large"/> <MeshMatrixMass massDensity="1" topology="@topo"/> <!-- 老师编辑器画面中增大到了100,使变形更明显 --> <ConstantForceField totalForce="100 0 0"/> <!-- 节点1和50完全固定 --> <FixedConstraint indices="1 50"/> <!-- 节点3:x方向自由,y和z方向固定 --> <PartialFixedConstraint indices="3" fixedDirections="0 1 1"/> <Node name="FineVisualModel"> <OglModel name="VisualModel" src="@../../meshLoaderFine"/> <BarycentricMapping name="VMapping" input="@../MechanicalModel" output="@VisualModel"/> </Node> </Node> </Node>

1.boundary conditions,边界条件

现在这个 SOFA 对象是 completely free to move,也就是完全自由运动。只要有外力,它整体就会被推走。

但真实仿真里,我们经常需要限制某些运动。例如:某些节点固定在墙上、某些节点只能沿某个方向滑动、某个区域被夹具固定、某个边界不能动。
这些就是boundary conditions,边界条件。它们的作用是限制物体的自由运动。

在 SOFA 中,一种常见方式是用:projective constraints,投影约束

其中一个最简单的就是:

<FixedConstraint indices="1 3 50" />

SOFA 中还有其他类型的约束,例如:把一个点连接到另一个点、两个物体之间建立接触关系、两个自由度必须满足某种方程……这些约束不一定用FixedConstraint这种投影方式处理。有些约束需要另一套求解方法,并且需要另一种 AnimationLoop,后面还会再回来讲这部分。

2.Projective Constraint 投影约束

2.1.FixedConstraint 是一种投影约束
<FixedConstraint indices="1 3 50" />

这行代码 <FixedConstraint indices="1 3 50" /> 意思是:把编号为 1、3、50 的节点固定住。

更具体一点:这些节点的全部自由度都被固定。因为当前MechanicalObject是:

<MechanicalObject template="Vec3d" ... />

每个Vec3d节点有三个自由度 x,y,z

完全固定表示这三个方向都不能运动:​=0,​=0,=0

2.2. 为什么叫“投影”约束

按照一个时间步解释其工作过程。

假设当前时间步是,

大致过程是:时间步开始 --> 把受约束节点的速度投影为0 --> 求解器计算新的位置和速度 --> 时间步结束 --> 再次把受约束节点投影回合法状态

在时间步开始,把节点1、3、50的速度投影为零;完成求解、得到新位置和新速度后,再次投影为零,从而确保这些节点不会移动。

3.检查被固定的节点

运行场景后,打开Behavior Models的显示,可以看到受约束的三个节点被突出显示。这三个节点正是:1、3、50。
代码中的indices指向的是力学网格的节点编号,而不是视觉网格上的三个任意点。

<TetrahedronSetGeometryAlgorithms template="Vec3d" name="GeomAlgo"/>

用 GeometryAlgorithms 显示节点编号:
前面讲过,它是一个几何工具包,可以进行体积计算;长度、面积等几何计算;几何信息可视化。
这里展示了它的另一个功能:在界面中显示各个网格点的编号。

4.固定节点后为什么物体仍然能变形

现在作用在这个 liver 上的外力是 ConstantForceField

<!-- <ConstantForceField totalForce="1 0 0"/> 为了让变形更明显,又改成了 --> <ConstantForceField totalForce="100 0 0"/>

这个 liver 已经具有:
MeshMatrixMass → 质量
TetrahedronFEMForceField → 线弹性材料行为
ConstantForceField → 外部节点力
FixedConstraint → 限制部分节点运动

ConstantForceField 是节点力( nodal force ),固定三个点不等于整个物体变成刚体,所以整个物体仍然可以产生弹性变形。

5.PartialFixedConstraint 部分固定约束

FixedConstraint会把一个节点的所有方向都锁死:x 固定 y 固定 z 固定
但有些物体需要像滑轨一样:允许沿 x 方向移动;禁止沿 y、z 方向移动

这时使用<PartialFixedConstraint/>

开始时三个节点全部固定:

<FixedConstraint indices="1 3 50"/>

为了让节点3只受到部分限制,需要先把节点3从完全固定中移除,然后单独添加:

<FixedConstraint indices="1 50"/> <PartialFixedConstraint indices="3" fixedDirections="0 1 1"/>

fixedDirections的三个数字依次对应x y z,其中 0 = 不固定,允许运动 ;1 = 固定,禁止运动。

这也是一种投影约束,只不过它只投影部分自由度。

二、重力

9-gravity.scn

<?xml version="1.0"?> <!-- Gravity applied to a deformable object --> <Node name="root" dt="0.01" gravity="0 -1 0"> <Node name="plugins"> <RequiredPlugin name="Sofa.Component.AnimationLoop"/> <RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <RequiredPlugin name="Sofa.Component.IO.Mesh"/> <RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <RequiredPlugin name="Sofa.Component.Mapping.NonLinear"/> <RequiredPlugin name="Sofa.Component.Mass"/> <RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <RequiredPlugin name="Sofa.Component.SolidMechanics.FEM.Elastic"/> <RequiredPlugin name="Sofa.Component.StateContainer"/> <RequiredPlugin name="Sofa.Component.Topology.Container.Dynamic"/> <RequiredPlugin name="Sofa.Component.Visual"/> <RequiredPlugin name="Sofa.GL.Component.Rendering3D"/> </Node> <DefaultAnimationLoop computeBoundingBox="false"/> <VisualStyle displayFlags="showForceFields"/> <MeshGmshLoader name="meshLoaderCoarse" filename="mesh/liver.msh"/> <MeshOBJLoader name="meshLoaderFine" filename="mesh/liver-smooth.obj"/> <Node name="Liver"> <EulerImplicitSolver/> <CGLinearSolver iterations="200" tolerance="1e-09" threshold="1e-09"/> <TetrahedronSetTopologyContainer name="topo" src="@../meshLoaderCoarse"/> <TetrahedronSetGeometryAlgorithms template="Vec3d" name="GeomAlgo"/> <MechanicalObject template="Vec3d" name="MechanicalModel" showObject="1" showObjectScale="3"/> <TetrahedronFEMForceField name="FEM" youngModulus="1000" poissonRatio="0.4" method="large"/> <!-- 重力必须通过质量转换成重力 --> <MeshMatrixMass massDensity="1" topology="@topo"/> <FixedConstraint indices="1 3 50"/> <Node name="FineVisualModel"> <OglModel name="VisualModel" src="@../../meshLoaderFine"/> <BarycentricMapping name="VMapping" input="@../MechanicalModel" output="@VisualModel"/> </Node> </Node> </Node>

1.Gravity

接下来打开 9-gravity.scn

场景根节点中有:

<Node name="root" dt="0.01" gravity="0 -1 0">

三个数依次表示:gx gy gz
gravity="0 -1 0" 表示重力加速度沿 y 轴负方向。
这里使用-1是为了演示。SOFA 不强制单位,如果采用国际单位制,地球重力通常会设置为接近: 0 -9.81 0 (前提是网格、质量、时间和材料参数也全部使用一致单位)

gravity特点:

  • 写的是加速度,而不是直接写力;
  • 必须通过质量得到重力;
  • 质量越大,对应的重力越大;
  • 只有包含质量组件的对象才会受到重力;
  • 根节点中的重力可以作用于其子树下所有有质量的力学对象。

2.重力如何变成力

重力加速度需要和质量结合,才能得到重力:

从连续体角度,更完整地说是把密度和重力加速度在物体体积内积分:

其中:

  • :质量密度;
  • :物体体积;
  • :重力加速度;
  • ​:最终装配到节点上的重力。

因此把重力称为:volumetric external force field 体积外力场。它作用于整个有质量的物体,而不是简单地手写一个节点力。

三、Other physical model — FEM、弹簧模型、非均匀刚度与阻尼

1.把 FEM 模型换成另一种物理模型

<TetrahedronFEMForceField name="FEM" youngModulus="1000" poissonRatio="0.4"/>

这个组件负责计算物体的线性弹性材料模型,也就是材料本构关系。

它把 liver 看成一个三维连续体,通过:

  • 四面体单元;
  • 杨氏模量youngModulus
  • 泊松比poissonRatio

计算物体受力后怎样变形、内部怎样产生恢复力。

把这一行换成另一个组件:

<MeshSpringForceField name="Springs" tetrasStiffness="10000"/>

组件名字是 Mesh Spring Force Field 网格弹簧力场,它是一个弹簧模型。

原来: TetrahedronFEMForceField ——> 把物体当成连续弹性材料

现在:MeshSpringForceField ——> 把网格节点之间的边看成弹簧

虽然场景中的 Loader、Topology、MechanicalObject、Mass、FixedConstraint、VisualModel、Mapping 都没有改变,但只替换这一行,物体的变形计算方法已经完全改变。

2.弹簧模型

FEM 模型认为这是一个连续物体,需要在空间中、在每个单元内部进行积分,并使用杨氏模量和泊松比等材料参数。

弹簧模型则更简单:不再仔细描述连续材料,直接在网格的边上放弹簧。

例如网格中有三个节点:

A ●────────● B \ / \ / \ / ● C

边:

A—B A—C B—C

都可以被看成弹簧。

因此:
节点 = 弹簧连接的位置
边 = 弹簧本身

这是一个非常基础的线性模型,不是像 FEM 那样对三维连续材料进行体积积分。

3.设置不同区域刚度

3.1.FEM 设置不同区域刚度

查看TetrahedronFEMForceField的属性。youngModulus并不一定只能是单个数值,它可以是:
vector<double> 双精度数值向量

情况一:只有一个值

youngModulus="1000"

表示所有四面体都使用同一个杨氏模量:

tetra 0 → 1000 tetra 1 → 1000 tetra 2 → 1000 ……

这就是均匀材料。

情况二:提供多个值

也可以为不同四面体提供不同的杨氏模量:

tetra 0 → 500 tetra 1 → 500 tetra 2 → 2000 tetra 3 → 2000

这样同一个物体中就可以出现一部分软,一部分硬。

3.2.弹簧模型如何设置不同刚度

打开MeshSpringForceField的属性窗口。

截图中可以看到一个弹簧列表,有914 个弹簧,每一行对应一根具体弹簧。

字段含义
Index 1弹簧第一个端点的节点编号
Index 2弹簧第二个端点的节点编号
stiffness(Ks)弹簧刚度
damping(Kd)弹簧阻尼
L弹簧静止长度或参考长度

刚度(stiffness)是材料力学中的名词,定义为施力与所产生变形量的比值,表示材料或结构抵抗变形的能力。公式记为

其中表示刚度,表示施力,表示变形量。在国际单位制中,刚度的单位为牛顿/米。一般应用于虎克定律作系统的振动分析。

阻尼(damping)是指任何振动系统在振动中,由于外界作用(如流体阻力、摩擦力等)和/或系统本身固有的原因引起的振动幅度逐渐下降的特性,以及此一特性的量化表征。

在实际振动中,由于摩擦力总是存在的,所以振动系统最初所获得的能量,在振动过程中因阻力不断对系统做负功,使得系统的能量不断减少,振动的强度逐渐减弱,振幅也就越来越小,以至于最后的停止振动,像这样的因系统的力学能,由于摩擦及转化成内能逐渐减少,振幅随时间而减弱振动,称为阻尼振动。

因此:

  • 弹簧模型可以为不同弹簧设置不同Ks
  • FEM 模型可以为不同四面体设置不同youngModulus

两种模型都能做非均匀刚度,只是控制对象不同

3.3.弹簧组件里的阻尼

MeshSpringForceField不仅能建立弹簧,还能建立一个基础的 spring-damper model 弹簧—阻尼器模型。
弹簧力主要取决于位移或伸长量,阻尼力主要与相对速度有关。

这里的边阻尼只是一个非常基础的阻尼模型,不一定适合所有材料。

“阻尼”可能有不同含义,要区分两种“阻尼”:

物理阻尼

如果你想模拟的是真实材料本身的黏性,例如:

  • 橡胶回弹有延迟;
  • 生物组织有黏性;
  • 软材料存在时间相关响应;

那么需要的是 Viscoelastic material 黏弹性材料

这种阻尼属于真实材料本构模型的一部分。SOFA 中已经有人开发了用于定义黏弹性材料的插件。

数值阻尼

另一种情况是:你并不一定要模拟真实黏性,只是想让仿真:

  • 更稳定;
  • 更快收敛;
  • 减少高频振荡;
  • 避免求解结果一直抖动。

这时使用的是 Numerical damping 数值阻尼,比如 Rayleigh damping 瑞利阻尼(数值阻尼的一种)
rayleighStiffness是 Rayleigh 数值阻尼,用于帮助仿真稳定,不一定代表真实材料的黏性。

数值阻尼是为了数值稳定而添加的,不一定对应真实材料中的黏性。甚至可以把它称为某种“fake damping”,意思不是它没用,而是它主要是数值计算手段,不一定代表真实物理材料。

http://www.jsqmd.com/news/1189035/

相关文章:

  • 虚拟主播面部捕捉技术:从证件照识别到实时渲染优化
  • 2026年北京手表回收:劳力士回收店面选择指南、价格透明、避坑技巧深度解析 - 奢侈品回收测评
  • 2026成都锦江Celine赛琳回收,腋下包、托特包专业无损鉴定 - 逸程奢侈品回收中心
  • 技术文档交付周期缩短68%的秘密:ChatGPT+Markdown+Swagger+Confluence四维协同工作流,附可复用的12个Prompt模板
  • 运维转大模型:别卷Prompt,先搞定“权限墙”与“可观测性”
  • C++内存管理实战:从RAII原理到智能指针应用与避坑指南
  • 薪资计算器只计算收入多少,编写程序,换算每份工作时消耗的内心热情值,优先推荐热情损耗最低的岗位,而非单纯高薪岗位。
  • 电力系统配网重构与二阶锥优化实战指南
  • 模板驱动型文档自动化:让结构化文档生成像印刷机一样精准
  • YOLO26的ProgLoss渐进式损失平衡源码解读:训练稳定性是如何被保障的?
  • C++高性能线程安全队列实现:从双锁设计到无锁优化
  • 外企年会“夹心层”测评:纯会务、本土创意、综合策划,谁能同时搞定总部审计和员工体验?
  • Mac上的Windows打印黑科技:用Whisky轻松驾驭跨平台打印难题
  • 江诗丹顿不是水鬼,别拿劳力士那套来估价|武汉7店实测报告 - 分享测评官
  • 欧米茄中国官方售后服务中心|服务电话及24小时维修地址权威信息通知(2026年7月更新) - 欧米茄服务中心
  • 基于YOLOv8的船舶类型检测系统:从数据准备到界面开发完整指南
  • 深度学习经典教材《Deep Learning》核心解析与实践指南
  • MrFlow:无需训练的扩散模型加速技术,实现10倍速度与画质无损
  • Python数据挖掘课程设计——基于数据挖掘的森林火灾风险等级评估与可视化预警系统(数据+模型+系统)
  • 复盘工具只总结成功经验,编写程序,专门归档日常小事里遗憾瞬间,从遗憾点挖掘可优化方向,转化为日常微创新清单。
  • AI期刊论文写作全攻略2026:投稿一次过的秘密武器
  • YOLOv8的C2f模块源码全解析:为什么它比C3更高效?
  • C++内存管理深度解析:realloc机制、陷阱与现代封装实践
  • MES系统实施落地为何如此艰难?——剖析制造执行系统的核心挑战与破局之道
  • 企业级 AI 应用工程实战(八):向量数据库选型与语义检索实现
  • 人工智能的现在与未来:从技术演进到产业融合的深度剖析
  • 2026东莞工厂搬迁电容器回收方案 陆浩整厂打包回收现款当场结算 - 广东再生资源回收
  • 天津旧金首饰黄金回收,不扣损耗不压价轻松高价变现 - 小蝶回收测评
  • 2026 适合国内学生日常穿搭的童装品牌?10 岁以上大童服饰品牌盘点 - 品牌种草官
  • 如何快速部署openeuler/Virt-docs虚拟化环境?3分钟上手安装教程