news 2026/9/14 14:11:47

SymPy 力学模块入门:质点、刚体、惯量、载荷与动能量函数 API 完全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SymPy 力学模块入门:质点、刚体、惯量、载荷与动能量函数 API 完全指南

SymPy 力学模块入门:质点、刚体、惯量、载荷与动能量函数 API 完全指南

【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy

SymPy 的sympy.physics.mechanics子模块为多体动力学建模提供了完整的符号计算基础:质点(Particle)、刚体(RigidBody)、惯量张量(Inertia)、载荷(Force / Torque),以及动量、动能、势能、拉格朗日量等系统级函数。本文以官方 API 参考页 part_bod.rst 为骨架,结合仓库源码与测试用例,系统讲解这些核心构件的数据结构、构造参数、物理公式与调用方式,帮助你直接写出可运行的多体系统动力学分析代码。

1. 总览:力学建模的基本构件

在 SymPy 多体动力学流程中,建模者通常先创建参考系(ReferenceFrame)与点(Point),再以它们为原料构造质点与刚体,最后通过Force/Torque施加载荷,并用动量、能量与拉格朗日函数做系统分析。这一流程对应的公共 API 全部由 mechanics/init.py 统一导出,包括ParticleRigidBodyinertiainertia_of_point_massInertiaForceTorquecenter_of_masslinear_momentumangular_momentumkinetic_energypotential_energyLagrangianfind_dynamicsymbols等。

所有"物体"类都继承自抽象基类 body_base.py 中的BodyBase,它统一提供了namemassmasscenterpotential_energy四个属性,并声明了kinetic_energylinear_momentumangular_momentumparallel_axis四个必须由子类实现的抽象方法。这意味着质点与刚体共享一致的"质量 + 质心 + 势能"接口,系统级函数可以对二者做统一遍历。

2. 质点 Particle

2.1 概念与构造参数

Particle表示一个具有非零质量但无空间延展的质点(见 particle.py)。构造时需提供三个参数,且初始化之后仍可修改:

参数类型含义默认行为
namestr质点名称,必须为字符串(否则抛TypeError必填
pointPoint表示该质点位置、速度、加速度的点缺省时自动生成名为{name}_masscenter的点
massSympifyable质点的质量表达式缺省时自动生成符号{name}_mass
from sympy.physics.mechanics import Particle, Point from sympy import Symbol po = Point('po') m = Symbol('m') pa = Particle('pa', po, m) # 初始化指定 pa.mass = m # 或者之后再修改 pa.point = po

从 body_base.py 的实现可以看到,缺省参数会被自动补齐:mass=None时创建符号Symbol(f'{name}_mass')masscenter=None时创建点Point(f'{name}_masscenter'),且potential_energy初始为0

2.2 动力学方法

Particle实现了BodyBase声明的四个抽象方法,公式与实现见 particle.py:

  • 线性动量linear_momentum(frame)L = m * v,其中v是质点在参考系frame中的速度。实现为self.mass * self.point.vel(frame)
  • 角动量angular_momentum(point, frame)H = cross(r, m * v)r为从point指向质点的位置矢量。
  • 动能kinetic_energy(frame)T = 1/2 * dot(m * v, v),实现为S.Half * self.mass * dot(self.point.vel(frame), self.point.vel(frame))
  • 平行轴定理parallel_axis(point, frame):返回该质点关于另一参考点与参考系的惯量并矢,内部直接调用inertia_of_point_mass
from sympy.physics.mechanics import Particle, Point, ReferenceFrame, dynamicsymbols from sympy.physics.vector import init_vprinting init_vprinting(pretty_print=False) m, v = dynamicsymbols('m v') N = ReferenceFrame('N') P = Point('P') A = Particle('A', P, m) P.set_vel(N, v * N.x) A.linear_momentum(N) # m*v*N.x

注意:set_potential_energy()方法自 SymPy 1.5 起已被弃用(sympy_deprecation_warning提示改用P.potential_energy = scalar属性赋值),新代码应直接使用BodyBase提供的potential_energy属性。

3. 刚体 RigidBody

3.1 概念与构造参数

RigidBody是一个"容器",存放描述理想刚体的全部要素:名称、质量、质心、固连参考系与惯量(见 rigidbody.py)。构造参数如下:

参数类型含义默认行为
namestr刚体名称必填
masscenterPoint刚体质心位置缺省自动生成{name}_masscenter
frameReferenceFrame与刚体固连的参考系缺省自动生成ReferenceFrame(f'{name}_frame')
massSympifyable刚体质量缺省自动生成符号{name}_mass
inertia(Dyadic, Point)关于某点的惯量并矢及参考点组成的二元组缺省自动生成六个惯量符号{name}_ixx{name}_iyy{name}_izz{name}_ixy{name}_iyz{name}_izx
from sympy import Symbol from sympy.physics.mechanics import ReferenceFrame, Point, RigidBody, outer m = Symbol('m') A = ReferenceFrame('A') P = Point('P') I = outer(A.x, A.x) # 惯量并矢 inertia_tuple = (I, P) # 必须为 (Dyadic, Point) 二元组 B = RigidBody('B', P, A, m, inertia_tuple) B.mass = Symbol('m2') # 之后仍可修改

3.2 惯量属性与中央惯量

RigidBodyinertia属性存储的是"关于某参考点 O 的惯量"(Dyadic, Point),而动力学公式(角动量、动能)使用的是中央惯量(关于质心的惯量并矢)。在 rigidbody.py 的inertiasetter 中,SymPy 会自动用平行轴定理做换算:

I_S/S* = I_S/O - I_S*/O

central_inertia = I[0] - inertia_of_point_mass(mass, masscenter.pos_from(point), frame)。因此:

  • 用户传入任意参考点的惯量,RigidBody都会自动缓存对应的central_inertia
  • central_inertia也可以直接设置,此时要求传入Dyadic,并自动将参考点重置为质心。

RigidBody还提供framexyz属性,分别返回固连参考系及其三个基矢量;framesetter 会校验类型,非ReferenceFrame时抛TypeError

3.3 动力学方法

  • 线性动量linear_momentum(frame)L = m * vv为质心速度,实现为self.mass * self.masscenter.vel(frame)
  • 角动量angular_momentum(point, frame)H = dot(I, w) + cross(r, m * v),其中I为中央惯量并矢,w为刚体在参考系frame中的角速度,r为参考点到质心的位置矢量。
  • 动能kinetic_energy(frame)T = 1/2 * (dot(dot(I, w), w) + dot(m * v, v)),即转动动能与平动动能之和;实现中将转动项S.Half * dot(self.frame.ang_vel_in(frame), dot(self.central_inertia, self.frame.ang_vel_in(frame)))与平动项分别计算后相加(见 rigidbody.py)。
  • 平行轴定理parallel_axis(point, frame=None):返回刚体关于另一参考点的惯量并矢central_inertia + inertia_of_point_mass(...)frame缺省时使用刚体自身固连系。
from sympy.physics.mechanics import Point, ReferenceFrame, outer, RigidBody, dynamicsymbols from sympy.physics.vector import init_vprinting init_vprinting(pretty_print=False) m, v, r, omega = dynamicsymbols('m v r omega') N = ReferenceFrame('N') b = ReferenceFrame('b') b.set_ang_vel(N, omega * b.x) P = Point('P') P.set_vel(N, v * N.x) I = outer(b.x, b.x) B = RigidBody('B', P, b, m, (I, P)) B.kinetic_energy(N) # m*v**2/2 + omega**2/2 B.angular_momentum(P, N) # omega*b.x

4. 惯量 Inertia

4.1inertia()函数:按张量分量构造并矢

inertia.py 中的inertia(frame, ixx, iyy, izz, ixy=0, iyz=0, izx=0)根据惯量张量的六个独立分量与一个固连参考系,构造惯量并矢:

参数默认值含义
frame惯量定义所在的参考系,必须是ReferenceFrame,否则抛TypeError
ixx,iyy,izz必填惯量张量的对角元(主惯量)
ixy,iyz,izx0惯量张量的非对角元(惯性积)

实现中会先将所有分量sympify,再按对称张量展开为 9 项并矢求和:

from sympy.physics.mechanics import ReferenceFrame, inertia N = ReferenceFrame('N') inertia(N, 1, 2, 3) # (N.x|N.x) + 2*(N.y|N.y) + 3*(N.z|N.z)

由 test_inertia.py 的测试可见,六个分量齐全时输出完整的 9 项对称形式(ixy同时出现在N.x|N.yN.y|N.x两个位置),且inertia(0, 0, 0, 0)这类非法首参会被raises(TypeError, ...)拦截。

4.2inertia_of_point_mass()函数:质点惯量

inertia_of_point_mass(mass, pos_vec, frame)返回关于点 Opos_vec的起点)的质点惯量并矢,其数学形式为:

I = m * ((x̂x̂ + ŷŷ + ẑẑ) * (r·r) - r⊗r)

其中r是从点 O 指向质点的位置矢量。例如质量为m、位于r * N.x的质点,惯量为m*r**2*(N.y|N.y) + m*r**2*(N.z|N.z)——这正是"轴向质量沿 x 轴时绕 y、z 轴有转动惯量"的物理结果,该断言同样出现在 test_inertia.py 中。

4.3Inertia类:并矢与参考点的成对封装

Inertia是一个namedtuple('Inertia', ['dyadic', 'point']),用于把惯量并矢与其参考点打包成一个对象(见 inertia.py):

  • 构造Inertia(dyadic, point),也接受Inertia(point, dyadic)的颠倒顺序(内部自动交换);dyadic必须是Dyadicpoint必须是Point,否则抛TypeError
  • from_inertia_scalars(point, frame, ixx, iyy, izz, ixy=0, iyz=0, izx=0):类方法,内部调用inertia()函数生成并矢后与点一起封装,参数含义与inertia()完全一致。
  • 矩阵视图I.dyadic.to_matrix(N)可直接输出 3×3 惯量矩阵,方便核对张量分量。
  • 不可运算Inertia不支持+*运算,会抛出带类型的TypeError,避免与普通元组混淆(测试见 test_inertia.py)。

RigidBody内部即以Inertia(I[0], I[1])形式保存惯量(见 rigidbody.py),因此body.inertia的取值与Inertia对象等价。

5. 载荷 Loads:Force 与 Torque

5.1Force:作用在点上的力

Force表示一个有作用线约束的力矢量(见 loads.py),存储"作用线上的一点 + 力矢量"二元组:

from sympy.physics.mechanics import Point, ReferenceFrame, Force N = ReferenceFrame('N') Po = Point('Po') Force(Po, 2 * N.x) # (Po, 2*N.x)

要点:

  • 首参可以是Point也可以是Particle/RigidBodyBodyBase对象——此时自动取该物体的质心body.masscenter
  • 类型校验严格:位置必须是Point、力必须是Vector,否则抛TypeError
  • 提供pointforce两个只读属性,分别等价于元组的locationvector

5.2Torque:作用在参考系上的力矩

Torque表示一个作用于参考系(进而作用于刚体)的自由矢量(见 loads.py):

from sympy.physics.mechanics import ReferenceFrame, Torque, RigidBody N = ReferenceFrame('N') Torque(N, 2 * N.x) # (N, 2*N.x) rb = RigidBody('rb', frame=N) Torque(rb, 2 * N.x) # 传入刚体时自动取 rb.frame

同样地,首参可以是ReferenceFrameBodyBase(自动取body.frame),且必须满足类型约束。

5.3 载荷的内部解析与配套工具

  • LoadBaseForce/Torque共同的抽象基类,同样禁止+/*运算(见 loads.py)。
  • 私有函数_parse_load()(见 loads.py)负责把(Point, Vector)元组解析为Force、把(ReferenceFrame, Vector)元组解析为Torque;元组长度不为 2 或首元素类型错误时抛ValueError,非元组非载荷类型则抛TypeError。对应边界行为在 test_loads.py 中有完整覆盖。
  • loads.py还提供了gravity(acceleration, *bodies)辅助函数,为任意数量的Particle/RigidBody批量生成重力载荷列表,每个载荷为Force(body.masscenter, body.mass * acceleration)

6. 系统级函数

以下函数位于 functions.py,均接受一个或多个Particle/RigidBody作为变长参数,对系统整体求值。

6.1center_of_mass(point, *bodies)

返回从给定点指向系统质心的位置矢量:Σ(mᵢ·rᵢ) / Σmᵢ。实现(见 functions.py)会遍历所有物体累计总质量与加权位置;对刚体取masscenter、对粒子取point属性;未传入任何物体时抛TypeError。文档中的完整示例同时混合了 4 个质点与 1 个刚体,并验证了加权质心表达式的正确性。

6.2 动量、能量与拉格朗日量

函数签名物理含义实现要点
linear_momentum(frame, *body)系统线性动量L = Σ m·v对所有物体调用各自的linear_momentum(frame)做矢量求和
angular_momentum(point, frame, *body)系统角动量H = Σ Hᵢ对所有物体调用angular_momentum(point, frame)求和
kinetic_energy(frame, *body)系统动能T = Σ Tᵢ(标量)求和各物体kinetic_energy(frame)
potential_energy(*body)系统势能V = Σ Vᵢ(标量)直接求和各物体potential_energy属性
Lagrangian(frame, *body)拉格朗日量L = T - V实现为kinetic_energy(frame, *body) - potential_energy(*body)

所有函数都会校验首参类型(ReferenceFrame/Point),并对非Particle/RigidBody的传入项抛TypeError(见 functions.py)。典型组合用法:

from sympy.physics.mechanics import (Point, Particle, ReferenceFrame, RigidBody, outer, linear_momentum, kinetic_energy, potential_energy, Lagrangian) from sympy import symbols M, m, g, h = symbols('M m g h') N = ReferenceFrame('N') O = Point('O') O.set_vel(N, 0 * N.x) P = O.locatenew('P', 1 * N.x) P.set_vel(N, 10 * N.x) Pa = Particle('Pa', P, 1) Ac = O.locatenew('Ac', 2 * N.y) Ac.set_vel(N, 5 * N.y) a = ReferenceFrame('a') a.set_ang_vel(N, 10 * N.z) I = outer(N.z, N.z) A = RigidBody('A', Ac, a, 20, (I, Ac)) Pa.potential_energy = m * g * h A.potential_energy = M * g * h linear_momentum(N, A, Pa) # 10*N.x + 500*N.y kinetic_energy(N, Pa, A) # 350 potential_energy(Pa, A) # M*g*h + g*h*m Lagrangian(N, Pa, A) # -M*g*h - g*h*m + 350

6.3find_dynamicsymbols(expression, exclude=None, reference_frame=None)

查找表达式中出现的所有动力学符号(随时间变化的dynamicsymbols),返回符号集合。其工作方式是收集表达式中free_symbols == {t}AppliedUndefDerivative原子(见 functions.py):

from sympy.physics.mechanics import dynamicsymbols, find_dynamicsymbols, ReferenceFrame x, y = dynamicsymbols('x, y') expr = x + x.diff() * y find_dynamicsymbols(expr) # {x(t), y(t), Derivative(x(t), t)} find_dynamicsymbols(expr, exclude=[x, y]) # {Derivative(x(t), t)} v = dynamicsymbols('a, b, c')[0] * ReferenceFrame('A').x # 简化示意

使用要点:

  • exclude可选,提供可迭代对象以排除已知符号;
  • 矢量表达式必须同时传入reference_frame,函数内部先to_matrix(frame)再分析,否则抛ValueError

7. 与后续建模工具的衔接

这些构件并非孤立存在:Force/Torque元组正是 KanesMethod 与LagrangesMethod等建模器的载荷输入格式;functions.py内部的_f_list_parser()(见 functions.py)会把(Point, force)(ReferenceFrame, torque)载荷列表解析为广义速度与广义力列表,供 Kane 方程与拉格朗日方程使用。RigidBodyParticle也可以直接作为System、关节(Joint)与执行器(Actuator)的构件输入。因此,熟练掌握本文的质点、刚体、惯量与载荷 API,是进一步使用KanesMethodLagrangesMethod等高层多体工具的前提。

8. 参考文件索引

  • 官方 API 参考页:part_bod.rst
  • 质点实现:particle.py
  • 刚体实现:rigidbody.py
  • 惯量实现:inertia.py
  • 载荷实现:loads.py
  • 系统级函数:functions.py
  • 物体抽象基类:body_base.py
  • 公共导出:mechanics/init.py
  • 相关测试:test_particle.py、test_rigidbody.py、test_inertia.py、test_loads.py、test_functions.py

【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 14:11:12

YooAsset深度解析:Unity资源管理与热更新工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 14:10:57

MATLAB透镜成像仿真:几何光学与菲涅尔衍射闭环实现

简介:这是一份面向光学初学者、物理实验教学及MATLAB入门者的透镜成像原理可视化学习工具,通过GUI交互式仿真帮助理解物距、像距、焦距等核心概念与薄透镜成像规律。资源包含17个文件,以13幅BMP格式的成像过程对比图(如Image_befo…

作者头像 李华
网站建设 2026/9/14 14:10:22

Python批量重命名照片:基于EXIF时间戳的自动化整理方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 14:07:59

HP1213tx仁宝代工笔记本非标维修实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华