弹性张量填充代码问题:为何生成45个独立分量而非36个?
弹性张量对称性填充问题
我正尝试编写代码来填充具有弹性张量对称性的张量,该张量应包含36个独立分量,满足对称性条件C[i,j,k,l] = C[j,i,k,l] = C[i,j,l,k]。
我的实现代码如下:
C = sym.MutableDenseNDimArray.zeros(3,3,3,3) var = sym.symbols('C1:%d'%82) ct = 0 for i in range(3): for j in range(3): for k in range(3): for l in range(3): if C[i,j,k,l] == 0: C[i,j,k,l] = var[ct] C[j,i,k,l] = var[ct] C[i,j,l,k] = var[ct] ct += 1
但这段代码生成了45个不同的分量,请问我哪里出错了?
问题原因
你的代码逻辑没考虑重复处理的冗余情况:弹性张量的这组对称性本质是把(i,j)和(k,l)分别看作对称二阶张量对,每个二阶对称张量有6个独立分量(3+2+1=6),6×6=36才是正确的独立分量总数。
而你的循环没有限制i<=j和k<=l的前提,导致会反复处理属于同一对称组的位置。比如当你处理(1,0,0,1)时,这个位置其实已经被(0,1,0,1)的对称赋值操作覆盖了,但循环顺序会让部分未被完全覆盖的位置被误判为新分量,最终多生成了9个冗余分量。
修正后的代码
通过限制i<=j和k<=l,确保每组对称对只被处理一次,同时覆盖所有对称位置:
import sympy as sym C = sym.MutableDenseNDimArray.zeros(3,3,3,3) # 生成36个独立变量(symbols左闭右开,所以到37) var = sym.symbols('C1:37') ct = 0 # 遍历对称的(i,j)对:i <= j for i in range(3): for j in range(i, 3): # 遍历对称的(k,l)对:k <= l for k in range(3): for l in range(k, 3): val = var[ct] # 给所有符合对称性的位置赋值 C[i,j,k,l] = val C[j,i,k,l] = val C[i,j,l,k] = val C[j,i,l,k] = val ct += 1 print(f"生成的独立分量数:{ct}") # 输出36
说明
- 限制
i<=j和k<=l后,(i,j)和(k,l)各有6组独立对,相乘正好得到36个独立分量。 - 每次赋值时覆盖所有4个对称位置,确保对称性条件被完整满足,不会出现遗漏或重复计数。
内容的提问来源于stack exchange,提问作者Chicha
相关产品推荐
相关产品推荐

