An introduction to scientific computing using free software FreeFem++ Ionut Danaila1 and Frédéric Hecht2 1 Université de Rouen Normandie, France 2 Université Pierre et Marie Curie, Paris August 8, 2021 I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 1 / 51 Outline 1 Scientific Computing and FreeFem++ Purpose of the Course Why using FreeFem++ Examples of complex problems computed with FreeFem++ 2 How to install FreeFem++ 3 Building a mesh with FreeFem++ 4 Finite-element spaces, 2d and 1d integrals 5 Solving the Poisson equation in 10 lines of code 6 From steady to time-dependent problems I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 2 / 51 Outline 1 Scientific Computing and FreeFem++ Purpose of the Course Why using FreeFem++ Examples of complex problems computed with FreeFem++ 2 How to install FreeFem++ 3 Building a mesh with FreeFem++ 4 Finite-element spaces, 2d and 1d integrals 5 Solving the Poisson equation in 10 lines of code 6 From steady to time-dependent problems I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 3 / 51 Scientific Computing = branch of Applied Maths Physics obs/equations Numerical meth. PDE/num analysis. Implementation Results algorithm/code physical detail Stages in Scientific Computing models –> mathematical theory of PDEs, numerical analysis –> mathematically sound methods, algorithms –> program (software) . Utility of a free easy-to-use software check mathematical theories, perform numerical experiments, initiate collaborations with physics and industry. I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 4 / 51 Stages in Scientific Computing: an example Num method. • Bose-Einstein • Gross-Pitaevskii (Schrödinger) eq. condensate • finite elements • experiment Physics Implementation Results agreement • num method • qualitative • algorithm • quantitative • software: FreeFem++ www.freefem.org JILA, Colorado I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 5 / 51 Why using FreeFem++ FreeFem++ (www.freefem.org) Free Generic PDE solver using finite elements (2D and 3D) syntax close to the mathematical formulation, powerful mesh generator, mesh interpolation and adaptivity, easy to implement weak formulations, use combined P1, P2 and P4 elements, complex matrices available, etc. You are welcome to participate in the: FreeFem++ Days, Paris, December, every year. I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 6 / 51 FreeFem++ syntax: close to mathematical formulation • create a mesh and a finite element space border circle(t=0,2*pi) {label=1;x=Rmax*cos(t);y=Rmax*sin(t);}; mesh Th=buildmesh(circle(nbseg)); fespace Vh(Th,P1); fespace Vh4(Th,P4); • solve −∆u = f in Ω and u = 0 on ∂Ω Vh u,v ; problem Lap(u,v) = int2d(Th)(u*v + dx(u)*dx(v)+dy(u)*dy(v)) - int2d(Th)(f*v) + on(1,u=0); Lap; plot(u); I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 7 / 51 Mesh adaptivity I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 8 / 51 Mesh isotropy I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 9 / 51 Computation of Bose-Einstein condensates Developers: G. Vergez (PhD student), I. Danaila, F. Hecht. submitted to CCP (to freely distribute scripts)! • stationary Gross-Pitaevskii (Schrödinger) equation 3D anisotropic mesh adaptation, flexibility for boundary conditions, I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 10 / 51 Computation of fluids with phase change • Navier-Stokes-Boussinesq equations + phase change, • I. Danaila, R. Moglan, F. Hecht, S. le Masson, JCP, 2014. ice formation Kowalewski & Rebow, Int. J. of Comput. Fluid Dynamics, 1999. I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 11 / 51 Outline 1 Scientific Computing and FreeFem++ Purpose of the Course Why using FreeFem++ Examples of complex problems computed with FreeFem++ 2 How to install FreeFem++ 3 Building a mesh with FreeFem++ 4 Finite-element spaces, 2d and 1d integrals 5 Solving the Poisson equation in 10 lines of code 6 From steady to time-dependent problems I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 12 / 51 How to install FreeFem++ FreeFem++: www.freefem.org pre-compiled versions for Windows and MacOS, compilation needed for Linux, to write programs/scripts: use your preferred Editor (Emacs). Explore www.freefem.org instructions for compilation, full documentation, slides from FreeFem++ days, etc lots of examples (.edp scripts). FreeFem++-cs: http://www.ann.jussieu.fr/∼lehyaric/ffcs/ pre-compiled versions for Windows, MacOS and Ubuntu, IDE integrated development environment, different graphical interface. I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 13 / 51 Outline 1 Scientific Computing and FreeFem++ Purpose of the Course Why using FreeFem++ Examples of complex problems computed with FreeFem++ 2 How to install FreeFem++ 3 Building a mesh with FreeFem++ 4 Finite-element spaces, 2d and 1d integrals 5 Solving the Poisson equation in 10 lines of code 6 From steady to time-dependent problems I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 14 / 51 Building a mesh with FreeFem++ (v01) Any computation starts with a mesh label=1 1 mesh circle v1.edp 0.5 y /* Mesh of a circle */ 0 // Parameters -0.5 int nbseg=100; real R=1, xc=0, yc=0; -1 -1 -0.5 0 x 0.5 1 // border border circle(t=0,2*pi){label=1; x=xc+R*cos(t); y=yc+R*sin(t);} plot(circle(nbseg),cmm="border"); // FE mesh mesh Th = buildmesh(circle(nbseg)); plot(Th, cmm="mesh of a circle"); I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 15 / 51 Building a mesh with FreeFem++ (v02) A mesh with a sub-domain:: + circle2(nbseg*2*pi*R2) mesh circle v2.edp 1 label=1 0.5 label=2 y /* Mesh of a circle with a subdomain */ // Parameters int nbseg=10;real R=1, xc=0, yc=0, R2=R/2; // borders border circle1(t=0,2*pi){label=1; x=xc+R*cos(t); y=yc+R*sin(t);} border circle2(t=2*pi,0){label=2; x=xc+R2*cos(t); y=yc+R2*sin(t);} plot(circle1(nbseg*2*pi*R)+circle2(-nbseg*2*pi*R2 ),cmm="border"); 0 -0.5 -1 -1 -0.5 0 x 0.5 1 // FE mesh mesh Th = buildmesh(circle1(nbseg*2*pi*R) +circle2(nbseg*2*pi*R2)); plot(Th, cmm="mesh of a circle with subdomain"); // Identify subdomains cout <<"inner region:: number ="<< I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. Th(xc,yc).region <<endl; cout <<"inner region:: number ="<< I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 16 / 51 Building a mesh with FreeFem++ (v03) A mesh with a hole inside:: + circle2(-nbseg*2*pi*R2) 1 label=1 0.5 label=2 /* Mesh of a circle with a hole inside */ // Parameters int nbseg=10; real R=1, xc=0, yc=0, R2=R/2; // border border circle1(t=0,2*pi){label=1; x=xc+R*cos(t); y=yc+R*sin(t);} border circle2(t=0,2*pi){label=2; x=xc+R2*cos(t); y=yc+R2*sin(t);} plot(circle1(nbseg*2*pi*R)+circle2(nbseg*2*pi*R2) ,cmm="border"); // FE mesh mesh Th = buildmesh(circle1(nbseg*2*pi*R) +circle2(-nbseg*2*pi*R2)); plot(Th, cmm="mesh of a circle with subdomain"); y mesh circle v3.edp 0 -0.5 -1 -1 -0.5 0 x 0.5 1 I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 17 / 51 Building a mesh with FreeFem++ (v04) A mesh with a hole inside:: using macros to avoid bugs be carreful with the syntax of EndOfMacro and inside comments mesh circle v4.edp /* Mesh of a circle with a hole inside using macros */ macro Bcircle(bname,Rm,xm,ym,labelm) /* circle border */ border bname(t=0,2*pi) {label=labelm; x=xm+Rm*cos(t);y=ym+Rm*sin(t);}//EOM // Parameters int nbseg=10; real R=1, xc=0, yc=0, R2=R/2; // borders Bcircle(circle1,R ,xc,yc,1); Bcircle(circle2,R2,xc,yc,2); plot(circle1(nbseg*2*pi*R)+circle2(nbseg*2*pi*R2),cmm="border"); // FE mesh mesh Th = buildmesh(circle1(nbseg*2*pi*R) +circle2(-nbseg*2*pi*R2)); I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. plot(Th, cmm="mesh of a circle with subdomain"); I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 18 / 51 Building a mesh with FreeFem++ (v05) Mesh for a half-disk:: check intersection points oriented borders (counter clockwise) 2.5 mesh circle v5.edp y 2 1.5 1 0.5 0 0.5 1 1.5 2 1.5 2 x 2.5 2 y /* Mesh of a half-disk */ // Parameters int nbseg=10; real R=1, xc=1, yc=1; // border border Dcircle(t=0, pi) {label=1; x=xc+R*cos(t); y=yc+R*sin(t);} border Daxis (t=xc-R,xc+R){label=2; x=t; y=yc;} plot(Dcircle(nbseg*pi*R)+Daxis(nbseg*2*R),cmm=" border"); // FE mesh mesh Th = buildmesh(Dcircle(nbseg*pi*R)+Daxis( nbseg*2*R)); plot(Th, cmm="mesh of a half-disk"); 1.5 1 0.5 0 0.5 1 x I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 19 / 51 Building a mesh with FreeFem++ (v06) Intermission: Mesh of a smiley 4 y 3 2 1 0 -1 0 1 x I. Danaila & F. Hecht 2 3 I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. Graduate Course on FreeFem++ August 8, 2021 20 / 51 Building a smiley with FreeFem++ (v06) mesh circle v6.edp /* Mesh of a smiley using macros */ macro Bellipse(bname,Rmx,Rmy,xm,ym,labelm) border bname(t=0,2*pi) {label=labelm; x=xm+Rmx*cos(t);y=ym+Rmy*sin(t);}//EOM // Parameters int nbseg=10; //head real Rh=2, xh=1, yh=2, Lh=2*pi*Rh; Bellipse(bs1,Rh,Rh,xh,yh,1); //eyes real xy1=xh+Rh/2*cos(pi/4), yy=yh+Rh/2*sin(pi/4), Ry=Rh/4, Ly=2*pi*Ry; Bellipse(bs2,Ry,Ry,xy1,yy,2); real xy2=xh-Rh/2*cos(pi/4); Bellipse(bs3,Ry,Ry,xy2,yy,3); //mouth real a=Rh/2, b=Rh/4, Lm=pi*sqrt(2*(aˆ2+bˆ2)); Bellipse(bs4,a,b,xh+0,yh-Rh/2,4); plot(bs1(nbseg*Lh)+bs2(nbseg*Ly)+bs3(nbseg*Ly)+bs4(nbseg*Lm)); // FE mesh mesh Th = buildmesh(bs1(nbseg*Lh)+bs2(-nbseg*Ly)+bs3(-nbseg*Ly)+bs4(nbseg*Lm)); I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. plot(Th, cmm="mesh of a smiley"); I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 21 / 51 Building the mesh of a rectangle (using ”square”) Mesh a rectangle:: using the built-in function ”square” 1 0.8 mesh rectangle v02.edp 0.6 0.4 /* Mesh of a rectangle using square function */ // Parameters int nbseg=10; real L=2,H=1; real xc1=0, yc1=0; // FE mesh mesh Th = square(nbseg*L, nbseg*H, [xc1+x*L,yc1+y*H]); plot(Th, cmm="mesh of a rectangle"); 0.2 0 0 0.5 1 1.5 2 0 0.5 1 1.5 2 1 0.8 0.6 0.4 0.2 0 I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 22 / 51 Building the mesh of a rectangle (using macros) mesh rectangle v01.edp /* Mesh of a rectangle */ macro Bsegment(bname,xP1,yP1,xP2,yP2,Ls,labelm) real Ls=sqrt((xP1-xP2)ˆ2+(yP1-yP2)ˆ2); border bname(t=0,Ls) {label=labelm; x=xP1+t*(xP2-xP1)/Ls; y=yP1+t*(yP2-yP1)/Ls;}//EOM // Parameters int nbseg=10; real L=2,H=1; real xc1=0, yc1=0, xc2=xc1+L,yc2=yc1, xc3=xc2, yc3=yc2+H, xc4=xc1, yc4=yc3+L; //borders Bsegment(bs1,xc1,yc1,xc2,yc2,Ls1,1); Bsegment(bs2,xc2,yc2,xc3,yc3,Ls2,2); Bsegment(bs3,xc3,yc3,xc4,yc4,Ls3,3); Bsegment(bs4,xc4,yc4,xc1,yc1,Ls4,4); plot(bs1(nbseg*Ls1)+bs2(nbseg*Ls2)+bs3(nbseg*Ls3)+bs4(nbseg*Ls4)); // FE mesh mesh Th = buildmesh(bs1(nbseg*Ls1)+bs2(nbseg*Ls2)+bs3(nbseg*Ls3)+bs4( nbseg*Ls4)); I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. plot(Th, cmm="mesh of a rectangle"); I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 23 / 51 Outline 1 Scientific Computing and FreeFem++ Purpose of the Course Why using FreeFem++ Examples of complex problems computed with FreeFem++ 2 How to install FreeFem++ 3 Building a mesh with FreeFem++ 4 Finite-element spaces, 2d and 1d integrals 5 Solving the Poisson equation in 10 lines of code 6 From steady to time-dependent problems I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 24 / 51 Finite element representation • Functional spaces ∂v ∂v , ∈ L2 (Ω)} ∂x ∂y V (Ω) = {v ∈ H 1 (Ω) : v |ΓD = 0}. H 1 (Ω) = {v ∈ L2 (Ω) : • Approximation spaces Th ::= triangulation, t Tk , (nt is the number of triangles). Ωh = ∪nk=1 Hh = {v ∈ C 0 (Ωh ) : ∀Tk ∈ Th , v |Tk ∈ P 1 (Tk )}, Vh = {v ∈ Hh : v |ΓD = 0}. h • Basis functions w i ∈ Hh , w i (q j ) = δij (1 if i = j, 0 otherwise). ∇w i |Tk = const, dim(Hh ) = nv (nv is the number of vertices), fh ∈ Hh ::= array of nv values. q2 q0 Tk q 1 ωi I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 25 / 51 Definition of finite element spaces, integrals FEspace is a type (as real or int) in FreeFem++ fespace v01.edp /* P1 representation */ // Parameters int nbseg=100; real R=1, xc=0, yc=0; // border border circle(t=0,2*pi){label=1;x=xc+R*cos(t); y=yc+R*sin(t);} // FE mesh mesh Th = buildmesh(circle(nbseg));plot(Th); // FE space fespace Vh(Th, P1); Vh u=x*x+y*y; plot(u, dim=3,fill=1,wait=1); // 2d integral cout.precision(12); real int2dU = int2d(Th)(u); cout <<"int2dU="<<int2dU<<endl; cout <<" exact="<<pi*Rˆ4/2<<endl; real int1dU = int1d(Th,1)(u); cout <<"int1dU="<<int1dU<<endl; cout <<" exact="<<2*pi*Rˆ3<<endl; I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 26 / 51 Functions: x, y , z are reserved names for space variables (part of) fespace v02.edp func fu=x*x+y*y; cout.precision(12); real int2dU = int2d(Th)(fu); cout <<"int2dU="<<int2dU<<endl; cout <<" exact="<<pi*Rˆ4/2<<endl; real int1dU = int1d(Th,1)(fu); cout <<"int1dU="<<int1dU<<endl; cout <<" exact="<<2*pi*Rˆ3<<endl; // other definition of functions func string infoMesh(mesh & Th) { string message="Mesh size:: nv="+ Th.nv+" nt="+Th.nt; return message; } cout << infoMesh(Th)<<endl; func real Meshsize(mesh & Th) { fespace Ph(Th,P0); Ph h=hTriangle; return h[].max; } I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. cout << Meshsize(Th)<<endl; I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 27 / 51 Outline 1 Scientific Computing and FreeFem++ Purpose of the Course Why using FreeFem++ Examples of complex problems computed with FreeFem++ 2 How to install FreeFem++ 3 Building a mesh with FreeFem++ 4 Finite-element spaces, 2d and 1d integrals 5 Solving the Poisson equation in 10 lines of code 6 From steady to time-dependent problems I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 28 / 51 The Poisson equation (1) • Deformation of a circular membrane −∆u = f for (x, y) ∈ D u =0 for (x, y) ∈ ∂D = C • Variational (weak) formulation: – multiply by a test function v ∈ V (D) = {v ∈ H 1 (D) : v |C = 0} C 0 x y f u – use Green’s formula (integration by parts) Z Z Z ∂u v dγ, [−v ∆u] dxdy = ∇v ∇u − D D C ∂n – to obtain (notice that v |C = 0) Z Z ∇v ∇u − fv = 0, D D I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 29 / 51 The Poisson equation (2) Z Z ∇v ∇u − D Z fv = 0 ⇔ D D ∂u ∂v ∂u ∂v + ∂x ∂x ∂y ∂y Z − fv = 0 D • derive the discrete weak formulation: FreeFem++ will take care! (part of) lap v01b.edp // Data of the problem func fs=4; // RHS (source) function // FE space fespace Vh(Th, P1); // Variational (weak formulation) Vh u,v; // u=unknown, v=test function problem Poisson(u,v) = int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v)) - int2d(Th)(fs*v) + on(1,u=0); // Dirichlet boundary condition // Solve the problem, plot the solution Poisson; plot(u,dim=2,fill=1); I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 30 / 51 The Poisson equation (3) • using a macro for i the gradient = column array of two componets h ∂u ∂u grad(u) = ∂x , ∂y and grad(u)0 is the transposed gradient (row array) (part of) lap v01.edp Vh u,v; // u=unknown, v=test function macro grad(u) [dx(u), dy(u)]//EOM problem Poisson(u,v)=int2d(Th)(grad(u)’*grad(v)) -int2d(Th)(fs*v) +on(1,u=0); // Dirichlet bc // Solve the problem, plot the solution Poisson; plot(u,dim=2,fill=1); // Compare with the exact solution Vh uexact=Rˆ2-xˆ2-yˆ2, error=abs(u-uexact); plot(error,dim=3,fill=1); cout.precision(12); I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 31 / 51 FreeFem++ program for the Poisson equation lap v01.edp /* Solving the Posson equation in a disk */ int nbseg=100;real R=1, xc=0, yc=0; border circle(t=0,2*pi){label=1;x=xc+R*cos(t); y=yc+R*sin(t);} mesh Th = buildmesh(circle(nbseg));plot(Th); // Data of the problem func fs=4; // RHS (source) function // FE space fespace Vh(Th, P1); // Variational (weak formulation) Vh u,v; // u=unknown, v=test function macro grad(u) [dx(u), dy(u)]//EOM problem Poisson(u,v)=int2d(Th)(grad(u)’*grad(v)) -int2d(Th)(fs*v) +on(1,u=0); // Dirichlet bc // Solve the problem, plot the solution Poisson; plot(u,dim=2,fill=1); // Compare with the exact solution Vh uexact=Rˆ2-xˆ2-yˆ2, error=abs(u-uexact); plot(error,dim=3,fill=1); cout.precision(12); cout<<"Maximum error ="<<error[].linfty<<endl; I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. cout<<"Maximum error ="<<error[].max<<endl; I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 32 / 51 Convergence of the FE method 1.000000 numerical result theoretical h2 0.100000 ku − uex k2 = (u − uex )2 Ω ku − uex k2 ≤ Ch2 0.010000 L2error sZ 0.001000 0.000100 0.000010 0.01 0.1 1 h I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 33 / 51 Convergence of the FE method (script part1) (part 1 of) lap v02.edp /* Convergence of the P1 FEM */ int nbseg=5;real R=1, xc=0, yc=0; border circle(t=0,2*pi){label=1;x=xc+R*cos(t); y=yc+R*sin(t);} mesh Th = buildmesh(circle(nbseg)); fespace Vh(Th, P1); func fs =4; // RHS (source) function func fex=Rˆ2-xˆ2-yˆ2; func real Meshsize(mesh & Th) { fespace Ph(Th,P0); Ph h=hTriangle; return h[].max; } Vh u,v,uexact,error; // u=unknown, v=test function macro grad(u) [dx(u), dy(u)]//EOM problem Poisson(u,v) = int2d(Th)(grad(u)’*grad(v)) - int2d(Th)(fs*v)+ on(1,u=0); // Dirichlet bc I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 34 / 51 Convergence of the FE method (script part 2) (part 2 of) lap v02.edp {verbosity=0; // lowest verbosity mode (no internal cout) ofstream ferror("lap_v02_error.dat"); real eL2, h, eL2old=1,hold=1; for(int irun=0;irun<8;irun++) { nbseg *= 2; Th=buildmesh(circle(nbseg)); Poisson; eL2 = sqrt(int2d(Th)(square(u-fex))); h = Meshsize(Th); real order =log(eL2/eL2old)/log(h/hold); eL2old=eL2; hold =h; cout<<"nbseg= "<<nbseg<<" Mesh size= "<<h <<" nv= "<<Th.nv <<" L2error= "<<eL2<<" order= "<<order<<endl; ferror<<h <<" "<<eL2<<" "<< order<<endl; } } I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 35 / 51 Convergence of the FE method 1.000000 numerical result theoretical h2 0.100000 ku − uex k2 = (u − uex )2 Ω ku − uex k2 ≤ Ch2 0.010000 L2error sZ 0.001000 0.000100 0.000010 0.01 0.1 h 1 Gnuplot commands set logscale xy plot "lap_v02_error.dat" w lp pt 7 t "num",x*x/6 w l t " theory" I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 36 / 51 Boundary conditions (1) • Consider the Poisson (heat) equation: −∆u = f , in Ω = [0, L] × [0, H] • with boundary conditions: H/2 Γ on Γ u = u Dirichlet BC 4 hot on Γ2 u = ucold Dirichlet BC -H/2 ∂u =0 Neumann BC on Γ1 ∂n ∂u + αu = 0 Fourier BC(α > 0) on Γ3 ∂n • Weak formulation: Z Z Z ∂u [−v ∆u] = ∇v ∇u − v, Ω Ω Γ ∂n Z Z Z ∂u fv − v = 0. ∇v ∇u − Ω Ω Γ ∂n Γ3 Γ2 4 L Γ1 Ω I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 37 / 51 Boundary conditions Z Z(2) Ω 4 Z X ∂u v = 0. ∇v ∇u − fv − Ω Γi ∂n i=1 Vh u,v; // u=unknown, v=test function problem Poisson(u,v) =int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v)) -int2d(Th)(fs*v) on Γ4 u = uhot Dirichlet v =0 +on(4, u = uhot) on Γ2 u = ucold Dirichlet v =0 +on(2, u = ucold); ∂u on Γ1 ∂u Neumann =0 ∂n = 0 ∂n nothing to be done ∂u = −αu on Γ3 ∂u ∂n + αu = 0 Fourier ∂n +int1d(Th, 3)(alpha ∗ u ∗ v ); Z Γ4 Z Γ2 Z Γ1 Z Γ3 ∂u v =0 ∂n ∂u v =0 ∂n ∂u v =0 ∂n ∂u v= ∂n Z (−αuv ) Γ3 I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 38 / 51 Exercises for the Poisson equation (1) In the previous problem (see lap v01.edp): we chose f = 4 corresponding to uex (x, y ) = R 2 − x 2 − y 2 which satisfies the BC. 1 Solve the same problem on the half disk. What BC should be applied at the axis (y = 0)? How this new BC appears in the variational formulation? 2 Solve the following PDE −∆u + u = f in R, and u|∂R = g, where R = [0, 1] × [0, 1] is a square domain. Find the expression for f (x, y ) and g(x, y ) such as that the exact solution should be uex (x, y) = 1 − x 2 − y 2 . I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 39 / 51 Exercises for the Poisson equation (2) 3 Potential flow around a cylinder (solution script: lap ex3.edp). For each point (x, y) the flow velocity is derived from the potential ϕ ∂ϕ ∂x → − v = ∇ϕ = ∂ϕ , −∆ϕ = 0. ∂y Ω = [0, L] × [−H, H]. The cylinder of radius r is centred in the domain. on Γ1 ∪Γ2 ∪Γ3 ∪Γ4 : ~v = v0 ~ex , on the cylinder Γ5 : H Γ3 Γ4 r Γ2 L 0 -H Ω Γ1 where ~ex is the unit vetor alog x-axis. ~v · ~n = 0, zero normal velocity. I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 40 / 51 Outline 1 Scientific Computing and FreeFem++ Purpose of the Course Why using FreeFem++ Examples of complex problems computed with FreeFem++ 2 How to install FreeFem++ 3 Building a mesh with FreeFem++ 4 Finite-element spaces, 2d and 1d integrals 5 Solving the Poisson equation in 10 lines of code 6 From steady to time-dependent problems I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 41 / 51 Solving the heat equation with various BC −∆θ = f in Ω, θ= T − Tcold Thot − Tcold smiley heat A.edp include "./mesh_circle_v6.edp"; // data real Tcold=20, Thot=300, dT=Thot-Tcold; real ThetaCold = 0;//(Tcold-Tcold)/dT real ThetaHot = 1;//(Thot-Tcold)/dT; real alpha=100; // FE space fespace Vh(Th, P1); // Variational (weak formulation) Vh u,v; // u=unknown, v=test function macro grad(u) [dx(u), dy(u)]//EOM problem Smiley(u,v)=int2d(Th)(grad(u)’*grad(v)) +int1d(Th,4)(alpha*u*v) //Fourier bc +on(2, u=ThetaCold) // Dirichlet bc +on(1, u=ThetaHot); // Dirichlet bc // Solve the problem, plot the solution Smiley; plot(u,dim=2,fill=1,cmm="Non-dim temp"); Vh T = u*dT+Tcold;plot(T,cmm="Temp dist"); cout <<"T min = "<< T[].min <<endl; I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. cout <<"T max = "<< T[].max <<endl; I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 42 / 51 Solving the heat equation in complex domains smiley heat B.edp include "./mesh_circle_v6.edp"; // New FE mesh Th = buildmesh(bs1(nbseg*Lh)+bs2(-nbseg*Ly)+bs3(-nbseg*Ly) +bs4(nbseg*Lm));plot(Th, cmm="New mesh of a smiley"); smiley heat B.edp fespace Vh(Th, P1); fespace Ph(Th, P0); // Identification of the mouth:: characteristic function int regMouth = Th(xh+0,yh-Rh/2).region; Ph IMouth = (region == regMouth)?1:0; plot(IMouth,cmm="Mouth",dim=3,wait=1); // Variational (weak formulation) Vh u,v; // u=unknown, v=test function macro grad(u) [dx(u), dy(u)]//EOM problem Smiley(u,v)=int2d(Th)(grad(u)’*grad(v)) -int2d(Th)(q*IMouth*v) //Fourier bc +on(2, u=ThetaCold) // Dirichlet bc +on(1, u=ThetaHot); // Dirichlet bc // Solve the problem, plot the solution I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 43 / 51 Solving the time-dependent heat equation (1) ∂θ − ∆θ = 0, for (x, y ) ∈ Ω, 0 ≤ t ≤ tmax ∂t +Boundary Conditions(in space) + Initial Condition(t = 0). • Discretisation in time (FD finite-difference type) [0, tmax ] = N−2 [ [tn , tn +δt], tn = nδt, n = 0, 1, . . . , N −1, δt = T /(N −1). n=0 Notation θn (x) = θ(x, tn ). θn+1 (x) − θn (x) − ∆θn+1 (x) = 0 δt θn+1 (x) − θn (x) − ∆θn (x) = 0 δt (implicit scheme) (explicit scheme) I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 44 / 51 Solving the time-dependent heat equation (2) • Discretisation in space (FE finite-element type): implicit scheme Z Ω Z Ω θn+1 v− δt θn+1 v− δt Z Ω Z Ω θn v+ δt θn v+ δt Z h i −v ∆θn+1 = 0 Z ∇θ Ω n+1 Z ∇v − Ω Γ ∂θn+1 v =0 ∂n • Weak formulation ready to use with FreeFem++: impose BC on θn+1 as for the steady problem. • In programs, in the ”time loop” we use only two variables: u = θn+1 and uold = θn . I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 45 / 51 Script for the time-dependent heat equation (1) (part 1 of) smiley heat C.edp include "./mesh_circle_v6.edp"; // data real Tcold=20, Thot=300, dT=Thot-Tcold; real ThetaCold = 0;//(Tcold-Tcold)/dT real ThetaHot = 1;//(Thot-Tcold)/dT; real alpha=100; //Time-evolution data real tmax=0.5, dt=0.01, idt=1./dt; // FE space fespace Vh(Th, P1); // Variational (weak formulation) Vh u,v, uold=0; // u=unknown, v=test function macro grad(u) [dx(u), dy(u)]//EOM problem SmileyT(u,v)=int2d(Th)(idt*u*v)-int2d(Th)(idt*uold*v) +int2d(Th)(grad(u)’*grad(v)) +int1d(Th,4)(alpha*u*v) //Fourier bc +on(2, u=ThetaCold) // Dirichlet bc +on(1, u=ThetaHot); // Dirichlet bc I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 46 / 51 Script for the time-dependent heat equation (2) (part 2 of) smiley heat C.edp //Time loop real t=0; int iter=0, nplot=2;Vh T; verbosity=0; while (t <= tmax) { iter++;t+=dt;SmileyT; if(!(iter%nplot))// visualisation every nplot { T = u*dT+Tcold; plot(T,cmm="Temp t="+t,fill=1); cout <<"t="<<t<<" T min= "<< T[].min <<" T max="<< T[].max <<endl; } uold=u; } I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 47 / 51 Solving the wave equation (1) ∂2u − ∆u = 0, ∂t 2 for (x, y) ∈ Ω, 0 ≤ t ≤ tmax +Boundary Conditions(in space) + Initial Condition for u, ∂u (t = 0). ∂t • Discretisation in time (FD finite-difference type) [0, tmax ] = N−2 [ [tn , tn +δt], tn = nδt, n = 0, 1, . . . , N −1, δt = T /(N −1). n=0 Notation u n (x) = u(x, tn ). u n+1 (x) − 2u n (x) + u n−1 (x) − ∆u n (x) = 0. δt 2 I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 48 / 51 Solving the wave equation (2) • Discretisation in space (FE finite-element type): implicit scheme Z Ω Z Ω u n+1 v− δt u n+1 v− δt Z Ω Z Ω 2u n v+ δt un v+ δt Z Ω Z Ω u n−1 v+ δt u n−1 v+ δt Z Z −v ∆u n = 0 Ω n Z ∇u ∇v − Ω Γ ∂u n v =0 ∂n • Weak formulation ready to use with FreeFem++: impose BC on u n as for the steady problem. • In programs, in the ”time loop” we use only three variables: u = u n+1 , uold = u n , uvold = u n−1 . I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 49 / 51 Script for the wave equation (1) (part 1 of) smiley heat D.edp include "./mesh_circle_v6.edp"; // New FE mesh (close the eyes and the mouth) Th = buildmesh(bs1(nbseg*Lh)+bs2(-nbseg*Ly)+bs3(nbseg*Ly) +bs4(nbseg*Lm));plot(Th, cmm="New mesh of a smiley"); //Time-evolution data real tmax=5, dt=0.01, idt2=1./(dt*dt); // FE space fespace Vh(Th, P1); // Variational (weak formulation) Vh u,v, uold=0,uvold=0; macro grad(u) [dx(u), dy(u)]//EOM problem SmileyW(u,v)=int2d(Th)(idt2*u*v)-int2d(Th)(2*idt2*uold*v)+int2d (Th)(idt2*uvold*v) +int2d(Th)(grad(uold)’*grad(v)) ; // only Neumann boundary conditions I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 50 / 51 Script for the wave equation (2) (part 2 of) smiley heat D.edp //Time loop real t=0; int iter=0, nplot=2; // Initial condition (u is Gaussian and du/dt=0) uvold = exp(-2*((x-xh)ˆ2 + (y-yh)ˆ2)); uold = uvold; u = uold; verbosity=0; while (t <= tmax) { iter++;t+=dt;SmileyW; if(!(iter%nplot))// visualisation every nplot { plot(u,cmm="Wave t="+t,fill=1,dim=3); cout <<"t="<<t<<" u min= "<< u[].min <<" u max="<< u[].max <<endl; } uvold=uold; uold =u; } I. Danaila & F. Hecht: Graduate Course on FreeFem++, Fields Institute, March 2016. I. Danaila & F. Hecht Graduate Course on FreeFem++ August 8, 2021 51 / 51