物理学中的潜在问题/高级主题/未来功能/向量模块

本文档将描述该模块提供的一些更高级的功能,但这些功能不属于“官方”接口的一部分。在这里,还将涵盖未来将实现的一些功能,以及关于适当功能的未解答问题。此外,还将讨论常见问题及其一些解决方案。

二元的

sympy.physics.mechanics 中,并矢用于表示惯性([Kane1985][WikiDyadics][WikiDyadicProducts])。并矢是一个由分量单位并矢组成的线性多项式,类似于向量是由分量单位向量组成的线性多项式。并矢是两个向量的外积,返回一个表示这两个向量并置的新量。例如:

\[\begin{split}\mathbf{\hat{a}_x} \otimes \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x} \\ \mathbf{\hat{a}_x} \otimes \mathbf{\hat{a}_y} &= \mathbf{\hat{a}_x} \mathbf{\hat{a}_y} \\\end{split}\]

其中 \(\mathbf{\hat{a}_x}\mathbf{\hat{a}_x}\)\(\mathbf{\hat{a}_x}\mathbf{\hat{a}_y}\) 是通过将左侧作为列向量与右侧作为行向量相乘得到的外积。注意顺序是重要的。

二元组的一些附加属性包括:

\[\begin{split}(x \mathbf{v}) \otimes \mathbf{w} &= \mathbf{v} \otimes (x \mathbf{w}) = x (\mathbf{v} \otimes \mathbf{w})\\ \mathbf{v} \otimes (\mathbf{w} + \mathbf{u}) &= \mathbf{v} \otimes \mathbf{w} + \mathbf{v} \otimes \mathbf{u}\\ (\mathbf{v} + \mathbf{w}) \otimes \mathbf{u} &= \mathbf{v} \otimes \mathbf{u} + \mathbf{w} \otimes \mathbf{u}\\\end{split}\]

参考系中的一个向量可以表示为 \(\begin{bmatrix}a\\b\\c\end{bmatrix}\)\(a \mathbf{\hat{i}} + b \mathbf{\hat{j}} + c \mathbf{\hat{k}}\)。类似地,一个并矢可以表示为张量形式:

\[\begin{split}\begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix}\\\end{split}\]

或以二元形式:

\[a_{11} \mathbf{\hat{a}_x}\mathbf{\hat{a}_x} + a_{12} \mathbf{\hat{a}_x}\mathbf{\hat{a}_y} + a_{13} \mathbf{\hat{a}_x}\mathbf{\hat{a}_z} + a_{21} \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} + a_{22} \mathbf{\hat{a}_y}\mathbf{\hat{a}_y} + a_{23} \mathbf{\hat{a}_y}\mathbf{\hat{a}_z} + a_{31} \mathbf{\hat{a}_z}\mathbf{\hat{a}_x} + a_{32} \mathbf{\hat{a}_z}\mathbf{\hat{a}_y} + a_{33} \mathbf{\hat{a}_z}\mathbf{\hat{a}_z}\\]

就像向量一样,后一种表示法使得可以跟踪哪些框架是相对于dyadic定义的。此外,dyadic中每一项的两个分量不必在同一个框架中。以下是有效的:

\[\mathbf{\hat{a}_x} \otimes \mathbf{\hat{b}_y} = \mathbf{\hat{a}_x} \mathbf{\hat{b}_y}\]

二元数也可以与向量进行叉乘和点乘;同样,顺序很重要:

\[\begin{split}\mathbf{\hat{a}_x}\mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x}\\ \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_y}\\ \mathbf{\hat{a}_x}\mathbf{\hat{a}_y} \cdot \mathbf{\hat{a}_x} &= 0\\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x}\mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x}\\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x}\mathbf{\hat{a}_y} &= \mathbf{\hat{a}_y}\\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} &= 0\\ \mathbf{\hat{a}_x} \times \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} &= \mathbf{\hat{a}_z}\mathbf{\hat{a}_x}\\ \mathbf{\hat{a}_x} \times \mathbf{\hat{a}_x}\mathbf{\hat{a}_x} &= 0\\ \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} \times \mathbf{\hat{a}_z} &= - \mathbf{\hat{a}_y}\mathbf{\hat{a}_y}\\\end{split}\]

也可以对并矢进行时间导数运算,或者在不同的坐标系中表达它们,就像对向量所做的那样。

常见问题

这里会出现数值积分代码的问题,坐标和速度表示的 \(dynamicsymbols\) 选择,打印、微分和替换的问题。

打印

默认的打印选项是对 VectorDyadic 测量编号进行排序,并且 vprintvpprintvlatex 函数的输出不排序。如果你打印的内容很大,请使用这些函数之一,因为排序可能会将打印时间从几秒增加到几分钟。

替换

代入大型表达式可能会很慢,并需要几分钟时间。

点的加速度

至少,点需要定义其速度,因为加速度可以通过在同一框架中对速度进行时间导数来计算。如果使用1点或2点定理来计算速度,速度表达式的时间导数可能会比使用加速度级别的1点和2点定理更复杂。使用加速度级别的方法可以在此阶段产生更短的表达式,这将导致后续更短的表达式(例如在形成Kane方程时)。

高级接口

在这里,我们将介绍以下内容中的高级选项:ReferenceFramedynamicsymbols 以及一些相关功能。

参考框架

ReferenceFrame 显示为具有 .name 属性和 .x.y.z 属性,用于访问基向量,以及一个定义相当严格的打印输出。如果您希望定义一组不同的索引,有一个选项可以实现这一点。这也将需要一个不同的接口来访问基向量。:

>>> from sympy.physics.vector import ReferenceFrame, vprint, vpprint, vlatex
>>> N = ReferenceFrame('N', indices=['i', 'j', 'k'])
>>> N['i']
N['i']
>>> N.x
N['i']
>>> vlatex(N.x)
'\\mathbf{\\hat{n}_{i}}'

此外,latex 输出可以有自定义字符串;不仅仅是索引,每个基向量的全部内容都可以被指定。自定义 latex 字符串可以在没有自定义索引的情况下出现,并且还会覆盖如果有自定义索引时将使用的 latex 字符串。:

>>> from sympy.physics.vector import ReferenceFrame, vlatex
>>> N = ReferenceFrame('N', latexs=['n1','\\mathbf{n}_2','cat'])
>>> vlatex(N.x)
'n1'
>>> vlatex(N.y)
'\\mathbf{n}_2'
>>> vlatex(N.z)
'cat'

dynamicsymbols

dynamicsymbols 函数还具有 ‘隐藏’ 功能;与时间相关的变量可以更改,打印导数的符号也可以更改。

>>> from sympy import symbols
>>> from sympy.physics.vector import dynamicsymbols, vprint
>>> q1 = dynamicsymbols('q1')
>>> q1
q1(t)
>>> dynamicsymbols._t = symbols('T')
>>> q2 = dynamicsymbols('q2')
>>> q2
q2(T)
>>> q1
q1(t)
>>> q1d = dynamicsymbols('q1', 1)
>>> vprint(q1d)
q1'
>>> dynamicsymbols._str = 'd'
>>> vprint(q1d)
q1d
>>> dynamicsymbols._str = '\''
>>> dynamicsymbols._t = symbols('t')

请注意,只有更改后创建的动态符号是不同的。对于 \(._str\) 属性则不然;这仅影响打印输出,因此更改前或更改后创建的动态符号将以相同的方式打印。

另请注意,Vector.dt 方法使用了 dynamicsymbols._t 属性,以及其他一些重要的函数和方法。不要混用表示时间的符号。

求解向量方程

要解决涉及向量的方程,你不能直接对向量使用求解函数。相反,你必须将向量转换为一组标量方程。

假设我们有两个坐标系 NA,其中 A 相对于 N 绕 z 轴旋转了 30 度。:

>>> from sympy import pi, symbols, solve
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame("N")
>>> A = ReferenceFrame("A")
>>> A.orient_axis(N, pi / 6, N.z)

假设我们有两个向量 v1v2,它们使用不同的符号表示同一个向量。:

>>> v1x, v1y, v1z = symbols("v1x v1y v1z")
>>> v2x, v2y, v2z = symbols("v2x v2y v2z")
>>> v1 = v1x * N.x + v1y * N.y + v1z * N.z
>>> v2 = v2x * A.x + v2y * A.y + v2z * A.z

我们的目标是找出在 v2 中使用的符号与在 v1 中使用的符号之间的关系。我们可以通过将向量转换为矩阵,然后使用 sympy.solvers.solvers.solve() 来解决矩阵来实现这一点。:

>>> solve((v1 - v2).to_matrix(N), [v2x, v2y, v2z])
{v2x: sqrt(3)*v1x/2 + v1y/2, v2y: -v1x/2 + sqrt(3)*v1y/2, v2z: v1z}