FEniCS2019定义子域材料触发警告,求UserExpression正确定义方法
解决FEniCS中UserExpression的"未提供value_shape或element"警告问题
这个警告的核心原因是FEniCS无法自动确定你定义的UserExpression是标量、向量还是张量类型,虽然它会默认假设为标量,但显式声明类型能消除警告,同时让代码逻辑更清晰。以下是两种可行的修正方案:
方案1:添加value_shape方法
在你的K类中添加value_shape方法,明确声明这是一个标量表达式(返回空元组()即可):
class K(UserExpression): def __init__(self, materials, k_0, k_1, **kwargs): super().__init__(**kwargs) self.materials = materials self.k_0 = k_0 self.k_1 = k_1 def eval_cell(self, values, x, cell): if self.materials[cell.index] == 0: values[0] = self.k_0 else: values[0] = self.k_1 def value_shape(self): return () # 显式指定为标量形状
方案2:实例化时指定element参数
如果你需要更精细地控制表达式的有限元空间(比如你的材料参数是单元恒定的,适合用分片常数元),可以在创建K实例时直接传入element参数:
# 保持K类定义不变,实例化时指定分片常数元 kappa = K(materials, 0.1, 1, element=ScalarElement("CG", mesh1.ufl_cell(), 0))
这里ScalarElement("CG", mesh1.ufl_cell(), 0)表示创建一个0次连续伽辽金标量元,对应分片常数的单元场,完全匹配你的材料参数定义逻辑。
修正后的完整代码(方案1示例)
from fenics import * mesh1 = RectangleMesh(Point(0, 0), Point(1, 1), 10, 10) tol = 1E-14 class Omega_0(SubDomain): def inside(self, x, on_boundary): return x[1] <= 0.5 + tol class Omega_1(SubDomain): def inside(self, x, on_boundary): return x[1] >= 0.5 - tol materials = MeshFunction('size_t', mesh1, mesh1.topology().dim()) subdomain_0 = Omega_0() subdomain_1 = Omega_1() subdomain_0.mark(materials, 0) subdomain_1.mark(materials, 1) class K(UserExpression): def __init__(self, materials, k_0, k_1, **kwargs): super().__init__(**kwargs) self.materials = materials self.k_0 = k_0 self.k_1 = k_1 def eval_cell(self, values, x, cell): if self.materials[cell.index] == 0: values[0] = self.k_0 else: values[0] = self.k_1 def value_shape(self): return () kappa = K(materials, 0.1, 1)
内容的提问来源于stack exchange,提问作者网创服务联盟
相关产品推荐
相关产品推荐

