下面我有一个使用索引表示法编写的等式。该等式可以用图中的六个等式表示。
使用索引表示法(爱因斯坦符号:https://en.wikipedia.org/wiki/Einstein_notation)扩展第一个等式。 在U_k中,k逗号是导数的约定。由于我们有重复索引(k,k),我们应用求和约定并得到(du_1 / dx_1 + du_2 / dx_2 + du_3 / dx_3)。在图中,术语u_1,u_2和u_3被写为u,v和w,它们由x_1,x_2和x_3(x,y和z)区分。
我是python和Sympy的新手,我看到有一个张量模块,但我看不出Sympy中是否已经实现了可以编写第一个等式(带索引)的内容,并从中获得了其他六个关系。
答案 0 :(得分:5)
目前,没有直接的方式来做你要求的事情。
我将通过使用 IndexedBase (即其他符号索引的符号)建议一个应该有效的技巧,然后替换。
声明你的符号:
U = IndexedBase("U")
l = symbols("lambda")
var("mu u v w x y z i j k")
声明你的表达式(没有爱因斯坦求和,所以明确地放一个 Sum ):
sij = l*Sum(U[k, k], (k, 0, 2)) * KroneckerDelta(i, j) + mu*(U[i, j] + U[j, i])
定义替换函数:将 U [0,0] 与 Derivative(u,x)匹配,依此类推:
def replace_U(uij):
i1, i2 = uij.indices
return Derivative([u, v, w][i1], [x, y, z][i2])
现在,首先使用整数值替换所有 i , j 索引替换 U [i,j] ,然后替换< em> U [0,0] ,...
for ii in range(3):
for ji in range(3):
if ii < ji:
continue
pprint(sij.doit().xreplace({i: ii, j: ji}).replace(lambda v: v.base == U, replace_U))
记住: Sum.doit()扩展总和。条件 ii&gt; = ji 用于避免两次打印相同的表达式(您的等式在 i,j 中是对称的。)
请注意,上面代码中的 U [i,j] 只是一个符号, i 和 j 除了as之外没有特殊含义 U 的索引。替换函数为它们分配衍生物。
我得到的输出是:
⎛d d d ⎞ d
λ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(u)
⎝dx dy dz ⎠ dx
⎛d d ⎞
μ⋅⎜──(u) + ──(v)⎟
⎝dy dx ⎠
⎛d d d ⎞ d
λ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(v)
⎝dx dy dz ⎠ dy
⎛d d ⎞
μ⋅⎜──(u) + ──(w)⎟
⎝dz dx ⎠
⎛d d ⎞
μ⋅⎜──(v) + ──(w)⎟
⎝dz dy ⎠
⎛d d d ⎞ d
λ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(w)
⎝dx dy dz ⎠ dz
我是python和Sympy的新手,我看到有一个张量模块 但我无法看到Sympy中是否已经实现了某些功能 在那里我可以写出第一个方程(带索引)并从中获得 其他六个关系。
有 sympy.tensor.tensor ,它支持抽象索引表示法(一种受限制的爱因斯坦求和)。不幸的是,它不支持衍生品。
如果您想处理组件,最近又添加了sympy.tensor.array。它提供多维数组,张量积和收缩,以及数组导数。
答案 1 :(得分:1)
如Francesco Bonazzi所述,还有另一种使用sympy.tensor.array来实现方程式的方法。该方法具有易于实现派生的优点。
示例代码如下:
from sympy import *
lam, mu, x, y, z = symbols("lambda mu x y z")
u, v, w = symbols("u v w", cls=Function)
du = derive_by_array([u(x, y, z), v(x, y, z), w(x, y, z)], [x, y, z])
sig = lam * tensorcontraction(du, (0, 1)) * eye(3) + mu * (du + transpose(du))
for i in range(3):
for j in range(i, 3):
Eq(Symbol("sigma_{}{}".format(i+1, j+1)), sig[i, j])
输出:
⎛∂ ∂ ∂ ⎞ ∂
σ₁₁ = λ⋅⎜──(u(x, y, z)) + ──(v(x, y, z)) + ──(w(x, y, z))⎟ + 2⋅μ⋅──(u(x, y, z))
⎝∂x ∂y ∂z ⎠ ∂x
⎛∂ ∂ ⎞
σ₁₂ = μ⋅⎜──(u(x, y, z)) + ──(v(x, y, z))⎟
⎝∂y ∂x ⎠
⎛∂ ∂ ⎞
σ₁₃ = μ⋅⎜──(u(x, y, z)) + ──(w(x, y, z))⎟
⎝∂z ∂x ⎠
⎛∂ ∂ ∂ ⎞ ∂
σ₂₂ = λ⋅⎜──(u(x, y, z)) + ──(v(x, y, z)) + ──(w(x, y, z))⎟ + 2⋅μ⋅──(v(x, y, z))
⎝∂x ∂y ∂z ⎠ ∂y
⎛∂ ∂ ⎞
σ₂₃ = μ⋅⎜──(v(x, y, z)) + ──(w(x, y, z))⎟
⎝∂z ∂y ⎠
⎛∂ ∂ ∂ ⎞ ∂
σ₃₃ = λ⋅⎜──(u(x, y, z)) + ──(v(x, y, z)) + ──(w(x, y, z))⎟ + 2⋅μ⋅──(w(x, y, z))
⎝∂x ∂y ∂z ⎠ ∂z
答案 2 :(得分:0)
这是我对这个问题的回答。代码显示/打印结果,并且不会因为按索引符号计算而给出错误。
欢迎评论进一步 (i) 适用于科学出版物的优化和打印结果。目前看起来很尴尬。
from sympy import Symbol, Derivative
from sympy import *
lam, mu, x, y, z = symbols("lambda mu x y z")
u, v, w = symbols("u v w", cls=Function)
du = derive_by_array([u(x, y, z), v(x, y, z), w(x, y, z)], [x, y, z])
sig = lam * tensorcontraction(du, (0, 1))*Array(eye(3)) + mu * (du + transpose(du))
alist = []
for i in range(3):
for j in range(i, 3):
alist.append(Eq(Symbol("sigma_{}{}".format(i+1, j+1)), sig[i, j]))
init_printing()