Windows子系统运行FEniCS时加法语句出现无效语法错误
解决FEniCS PDE求解代码中的语法与逻辑问题
别担心,刚接触FEniCS和Python遇到这类问题太正常了!我帮你梳理下代码里的几个关键问题,修复后应该就能正常运行了:
核心错误梳理
- L1表达式括号不匹配+冗余
dx:这是触发语法错误的根源,原L1末尾缺少闭合括号,而且最后-gamma*u0[1]后面多了一个不必要的*dx,导致Python解析失败,报错位置可能指向后面的a = a0 + a1,但实际错误在L1定义处。 - 函数拼写错误:
asseble(L)应该是assemble(L),少了一个字母s。 - 未定义变量:代码中使用
uv但从未定义,实际应该是你要保存的解变量u。 - InitialConditions类的eval方法错误:直接给
values赋值Expression对象是错误的,应该直接计算数值结果赋值,因为eval方法需要的是具体数值而非表达式对象。 - 冗余边界条件代码:你先定义了DirichletBC又立刻覆盖为
bc = [],可以直接保留Neumann边界的定义。
修正后的完整代码
from fenics import * # Create mesh and define function space mesh = Mesh("circle.xml") # Construct the finite element space V = VectorFunctionSpace(mesh, 'P', 1) # Define parameters: T = 150 dt = 0.5 alpha = 0.4 beta = 2 gamma = 0.8 delta = 1 # Class representing the initial conditions class InitialConditions(UserExpression): def eval(self, values, x): # 直接计算数值赋值,而非返回Expression对象 values[0] = (4/25) - 2e-7 * (x[0] - 0.1*x[1] - 225) * (x[0] - 0.1*x[1] - 675) values[1] = (22/45) - 3e-5 * (x[0] - 450) - 1.2e-4 * (x[1] - 150) def value_shape(self): return (2,) # Define initial condition indata = InitialConditions(degree=2) u0 = interpolate(indata, V) # 合并赋值语句,避免重复赋值 # Test and trial functions u, v = TrialFunction(V), TestFunction(V) # Create bilinear and linear forms a0 = (u[0]*v[0]*dx) + (0.5*delta*dt*inner(grad(u[0]), grad(v[0]))*dx) a1 = (u[1]*v[1]*dx) + (0.5*delta*dt*inner(grad(u[1]), grad(v[1]))*dx) # 修复L0的冗余dx(原代码里多了一个*dx)和L1的括号与冗余dx L0 = (u0[0]*v[0]*dx) - (0.5*delta*dt*inner(grad(u0[0]), grad(v[0]))*dx) - (dt*u0[0]*v[0]*(((u0[0]*u0[1])/(u0[0]+alpha)) - u0[0]*(1-u0[0]))*dx) L1 = (u0[1]*v[1]*dx) - (0.5*delta*dt*inner(grad(u0[1]), grad(v[1]))*dx) - (dt*u0[1]*v[1]*(-beta*((u0[0]*u0[1])/(u0[0]+alpha)) - gamma*u0[1])*dx) a = a0 + a1 L = L0 + L1 # Set up boundary condition(直接使用Neumann边界) bc = [] # Assemble matrix A = assemble(a) # Set an output file out_file = File("Results.pvd", "compressed") # Set initial condition u = Function(V) u.assign(u0) t = 0.0 out_file << (u, t) u_initial = Function(V) u_initial.assign(u0) t_save = 0 num_samples = 20 # Time - stepping while t < T: # assign u0 u0.assign(u) # Assemble vector and apply boundary conditions A = assemble(a) b = assemble(L) # 修复拼写错误 bc.apply(A, b) # 应用边界条件(即使是Neumann,这一步也可以保留) t_save += dt if t_save > T / num_samples or t >= T - dt: print("Saving!") # Save the solution to file(修复uv为u) out_file << (u, t) t_save = 0 # Solve the linear system solve(A, u.vector(), b) # Move to next interval t += dt
额外说明
- 我还修复了L0里多余的
*dx(原代码中...*(1-u0[0]))*dx)多了一个dx),这会导致FEniCS无法正确识别积分形式。 - 在时间循环里添加了
solve(A, u.vector(), b),原代码里只组装了矩阵和向量,但没有求解线性系统,这会导致解不会更新。
内容的提问来源于stack exchange,提问作者Kate
相关产品推荐
相关产品推荐

