我使用Freefem ++来解决泊松方程
Grad ^ 2 u(x,y,z)= - f(x,y,z)
当我有f的解析表达式时,它运行良好,但现在我有一个f数字定义(即在网格上定义的一组数据),我想知道我是否仍然可以使用Freefem ++。
即。典型代码(在这种情况下为2D问题),如下所示
mesh Sh= square(10,10); // mesh generation of a square
fespace Vh(Sh,P1); // space of P1 Finite Elements
Vh u,v; // u and v belongs to Vh
func f=cos(x)*y; // analytical function
problem Poisson(u,v)= // Definition of the problem
int2d(Sh)(dx(u)*dx(v)+dy(u)*dy(v)) // bilinear form
-int2d(Sh)(f*v) // linear form
+on(1,2,3,4,u=0); // Dirichlet Conditions
Poisson; // Solve Poisson Equation
plot(u); // Plot the result
我想知道我是否可以用数字来定义f,而不是分析。
答案 0 :(得分:3)
网格&空间定义
我们定义一个Nx = 10 mesh且Ny = 10的正方形单位,这在x轴上提供了11个节点,在y轴上提供了相同的节点。
int Nx=10,Ny=10;
int Lx=1,Ly=1;
mesh Sh= square(Nx,Ny,[Lx*x,Ly*y]); //this is the same as square(10,10)
fespace Vh(Sh,P1); // a space of P1 Finite Elements to use for u definition
条件和问题陈述
我们不打算使用求解,但我们将处理矩阵(使用FreeFem解决更复杂的方法)。
首先我们为我们的问题定义CL(Dirichlet)。
varf CL(u,psi)=on(1,2,3,4,u=0); //you can eliminate border according to your problem state
Vh u=0;u[]=CL(0,Vh);
matrix GD=CL(Vh,Vh);
然后我们定义问题。我建议使用宏,而不是写dx(u)*dx(v)+dy(u)*dy(v)
,所以我们将div定义为以下内容,但请注意//
NOT ;
的宏完成。
macro div(u) (dx(u[0])+dy(u[1])) //
因此Poisson双线性形式变为:
varf Poisson(u,v)= int2d(Sh)(div(u)*div(v));
我们提取Stifness矩阵后
matrix K=Poisson(Vh,Vh);
matrix KD=K+GD; //we add CL defined above
我们继续解决,UMFPACK是FreeFem中的解算器,对此并不太关注。
set(KD,solver=UMFPACK);
这就是你需要的。您想在某些特定节点上定义函数f的值。我将给你秘密,泊松线性形式。
real[int] b=Poisson(0,Vh);
您可以在要执行的任何节点上定义函数f的值。
b[100]+=20; //for example at node 100 we want that f equals to 20
b[50]+=50; //and at node 50 , f equals to 50
我们解决了我们的系统。
u[]=KD^-1*b;
最后我们得到了情节。
plot(u,wait=1);
我希望这对你有所帮助,感谢我的实习主管Olivier,他总是特意在FreeFem上给我一些技巧。我测试过,效果很好。祝你好运。
答案 1 :(得分:0)
afaf 的方法适用于函数f
是独立函数的情况。对于像int2d(Sh)(f*u*v)
这样的术语,需要另一种解决方案。我建议(实际上我在Hecht的手册中将它改为红色)一种涵盖两种情况的方法。但是,它仅适用于P1
有限元,其自由度与网格节点重合。
fespace Vh(Th,P1);
Vh f;
real[int] pot(Vh.ndof);
for(int i=0;i<Vh.ndof;i++){
pot[i]=something; //assign values or read them from a file
}
f[]=pot;