我是 Fenics 的新手,刚开始阅读使用Python 求解 PDE的教程。为简单起见,我们可以参考最简单的示例,第 17 页(线性泊松方程),尽管没有必要。
我的问题是:给定一个固定的 PDE,用不同的参数多次求解。(例如,改变上述例子中的常数 f)。
我的 30 秒尝试(如上面链接中的符号):
samples = 10
def solver(x, y):
#x is the parameter to vary,
#y the variable containing my solution
f = Constant(x)
L = f*v*dx
u = Function(V)
solve(a == L, u, bc)
#write part of the solution in y
for i in range(samples):
#set x, y as appropriate
solver(x,y)
完成这项工作,但是当样本达到 100.000 左右(我需要的数量)时,它需要大量的时间和内存(通常进程结束被杀死)。我的问题是:我怎样才能加快速度?
我的想法是:由于 PDE 总是相同的,因此必须有一种方法,例如存储一次刚度矩阵,然后每次都使用它,将“求解器”简化为线性代数乘法。另一方面,我不知道如何与 fenics 正确交互。任何建议都将不胜感激。
解决方案 cpraveen给出的答案解决了这个问题。这里有一个原始但有效的代码,可能对其他读者有用。
from fenics import *
import numpy as np
## Commets omitted for simplicity: standard introduction
mesh = UnitSquareMesh(8,8)
V = FunctionSpace(mesh, 'P', 1)
u_D = Expression('1 + x[0]*x[0] + 2*x[1]*x[1]', degree=2)
def boundary(x, on_boundary):
return on_boundary
bc = DirichletBC(V, u_D, boundary)
u = TrialFunction(V)
v = TestFunction(V)
a = dot(grad(u), grad(v))*dx
print("1")
# New suggested trick
A = assemble(a)
bc.apply(A)
solver = LUSolver(A)
#solver.parameters['reuse_factorization'] = True # <- deprecated!
print("2")
# ...and define the solver accordingly
def my_solver(x):
f = Constant(x[0])
b = assemble(f*v*dx)
bc.apply(b)
L = f*v*dx
u = Function(V)
solver.solve(u.vector(), b)
# Start multiple resolutions
print("Go!")
samples = 10
for i in range(10):
my_solver([i])
print(i)