Skip to main content

Distributed Lagrange Multiplier for Fluid-Structure Interactions

  • Chapter
  • First Online:
Book cover Numerical Methods for PDEs

Part of the book series: SEMA SIMAI Springer Series ((SEMA SIMAI,volume 15))

  • 1355 Accesses

Abstract

In this paper we make preliminary numerical tests to assess the performance of the scheme introduced in Boffi et al. (SIAM J Numer Anal 53(6):2584–2604, 2015) and analyzed in Boffi and Gastaldi (Numer Math 135(3):711–732, 2017) for the approximation of fluid-structure interaction problems. We show how to implement the scheme within the FreeFem++ framework (Hecht, J Numer Math 20(3–4):251–265, 2012) and validate our code with respect to some known problems and benchmarks. The main conclusion is that a simple implementation can provide quite accurate results for non trivial applications.

This is a preview of subscription content, log in via an institution to check access.

Access this chapter

Chapter
USD 29.95
Price excludes VAT (USA)
  • Available as PDF
  • Read on any device
  • Instant download
  • Own it forever
eBook
USD 84.99
Price excludes VAT (USA)
  • Available as EPUB and PDF
  • Read on any device
  • Instant download
  • Own it forever
Softcover Book
USD 109.99
Price excludes VAT (USA)
  • Compact, lightweight edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info
Hardcover Book
USD 109.99
Price excludes VAT (USA)
  • Durable hardcover edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info

Tax calculation will be finalised at checkout

Purchases are for personal use only

Institutional subscriptions

References

  1. Boffi, D., Gastaldi, L.: A fictitious domain approach with Lagrange multiplier for fluid-structure interactions. Numer. Math. 135(3), 711–732 (2017)

    Article  MathSciNet  Google Scholar 

  2. Boffi, D., Gastaldi, L., Heltai, L., Peskin, C.S.: On the hyper-elastic formulation of the immersed boundary method. Comput. Methods Appl. Mech. Eng. 197(25–28), 2210–2231 (2008)

    Article  MathSciNet  Google Scholar 

  3. Boffi, D., Brezzi, F., Fortin, M.: Mixed Finite Element Methods and Applications. Springer Series in Computational Mathematics, vol. 44. Springer, New York (2013)

    Book  Google Scholar 

  4. Boffi, D., Cavallini, N., Gastaldi, L.: The finite element immersed boundary method with distributed Lagrange multiplier. SIAM J. Numer. Anal. 53(6), 2584–2604 (2015)

    Article  MathSciNet  Google Scholar 

  5. Dunne, Th., Rannacher, R., Richter, Th.: Numerical simulation of fluid-structure interaction based on monolithic variational formulations. In: Fundamental Trends in Fluid-Structure Interaction. Contemporary Challenges in Mathematical Fluid Dynamics and its Applications, vol. 1, pp. 1–75. World Scientific Publishing, Hackensack (2010)

    Google Scholar 

  6. Girault, V., Glowinski, R.: Error analysis of a fictitious domain method applied to a Dirichlet problem. Jpn. J. Ind. Appl. Math. 12(3), 487–514 (1995)

    Article  MathSciNet  Google Scholar 

  7. Hecht, F.: New development in FreeFem++. J. Numer. Math. 20(3–4), 251–265 (2012)

    MathSciNet  MATH  Google Scholar 

  8. Hecht, F., Pironneau, O.: An energy stable monolithic Eulerian fluid-structure finite element method. Int. J. Numer. Methods Fluids 85(7), 430–446 (2017)

    Article  MathSciNet  Google Scholar 

  9. Peskin, C.S.: The immersed boundary method. Acta Numer. 11, 479–517 (2002)

    Article  MathSciNet  Google Scholar 

  10. Pironneau, O.: On the transport-diffusion algorithm and its applications to the Navier-Stokes equations. Numer. Math. 38(3), 309–332 (1981/82)

    Article  MathSciNet  Google Scholar 

  11. Wang, Y., Jimack, P.K., Walkley, M.A.: A one-field monolithic fictitious domain method for fluid–structure interactions. Comput. Methods Appl. Mech. Eng. 317, 1146–1168 (2017)

    Article  MathSciNet  Google Scholar 

  12. Zhao, H., Freund, J.B., Moser, R.D.: A fixed-mesh method for incompressible flow-structure systems with finite solid deformations. J. Comput. Phys. 227(6), 3114–3140 (2008)

    Article  MathSciNet  Google Scholar 

Download references

Author information

Authors and Affiliations

Authors

Corresponding author

Correspondence to Daniele Boffi .

Editor information

Editors and Affiliations

Appendices

Appendix 1: FreeFem++ Codes

Listing 5.1 Code for the falling disk

1 int n=20, m=8*n;   // higher for fine mesh 3 int H=4, W=2;  // vertical length of fluid box 4 real h=0.5, R1=0.125*2, R2=R1, xc=W/2, yc=H-h;   // elliptic radii and center of disk 5 real rhof=1, rhos=1.2, nu=1, penal=1e-9; 6  // rho, mu, rescaled : divided by 1e6 7 real  kappa=0.3,  /*E=1e4, mu=E/(1+kappa)/2 */ mu=1e1, lambda=2*kappa*mu/(1-2*kappa); 8 real gravity=981; 9 real T=0.7, dt=0.1/n, dt2=dt*dt; 10 real c1=1, c2=10;  // Lagrange multiplier constants: H1 -> 1,1, L2 -> 0,1 12  // mesh Thf=square(10*n,H*n,[x,H*y]); // fluid + solid domain 14 border a1(t=0,1){x=W*t; y=0;} 15 border a2(t=0,1){x=W; y=H*t;} 16 border a3(t=1,0){x=W*t; y=H;} 17 border a4(t=1,0){x=0;y=H*t;} 18 border C(t=0,2*pi){x=xc+R1*cos(t); y=yc+R2*sin(t);} 19 mesh Thsi = buildmesh(C(m));  // Initial solid domain 20 fespace Whi(Thsi,P1); 21 Whi Xoi=x,Yoi=y; 22 real[int] xx(m), yy(m); 23 int[int] nn(m); 24 for(int i=0;i<m;i++){xx[i]=xc+R1*cos(2*i*pi/(m)); yy[i]=yc+R2*sin(2*i*pi/(m)); nn[i]=2;} 25 border D(t=0,1;i){ 26         int ii = (i+1)%m; real t1 = 1-t; real x1 = xx[i]*t1 + xx[ii]*t; 27         real y2 = yy[i]*t1 + yy[ii]*t; x= Xoi(x1,y2); y=Yoi(x1,y2); 28 } 29 plot(D(nn)); 30 mesh Ths = buildmesh(D(nn)); 31 mesh Thso=Ths; 32 mesh Thf= buildmesh(a1(W*n/2)+a2(H*n)+a3(W*n)+a4(H*n)+D(nn)); 33  //plot(a1(10*n)+a2(H*n)+a3(10*n)+a4(H*n)+D(nn)); 34 plot(Thf,Thso, cmm= "Initial configuration"); 36 fespace Vh(Thf,P1b);   // velocity space 37 fespace Qh(Thf,P1);   // pressure space 38 fespace Wh(Ths,P1b);   // Lagrangian coordinates X,Y space 39 fespace Lh(Ths,P1);   // Lagrangian multiplier space 40 fespace Zh(Thf,[P1b,P1b,P1]);  // fluid space 41 fespace Rh(Ths,[P1,P1,P1b,P1b]); // solid space 43 Vh u,v,uh,vh; 44 Qh p,ph; 45 Wh  Xoo=x-0.*(x-xc),Yoo= y-0.*(y-yc);  // the X,Y are now the displacements 46 Rh [lamx,lamy,X,Y],[lamxo,lamyo,Xo,Yo]=[0,0,x,y]; //x-(x-xc)/2,y+(y-yc)/2]; 47 Zh [uo,vo,po]=[0,0,0]; 49 macro div(u,v) ( dx(u)+dy(v) )  // EOM 50 macro Grad(u,v)[[dx(u),dy(u)],[dx(v),dy(v)]]  // EOM 51 macro DD(u,v)  [[2*dx(u),div(v,u)],[div(v,u),2*dy(v)]]  // EOM 53 varf aa([u,v,p],[uh,vh,ph]) = 54           int2d(Thf)(rhof*[u,v] ’*[uh,vh]/dt- div(uh,vh)*p -div(u,v)*ph 55                      + penal*p*ph + nu*trace(DD(uh,vh)’*DD(u,v))/2) 56           + on(1,3,u=0,v=0) + on(2,4,u=0) ; 58 varf bb([lamx,lamy,X,Y],[lamxh,lamyh,Xh,Yh]) = 59           int2d(Ths)((rhos-rhof)*(X*Xh+Y*Yh)/dt2 60                      - c1*trace(Grad(lamx,lamy) ’*Grad(Xh,Yh)) - c2*(lamx*Xh+lamy*Yh) 61                      - c1*trace(Grad(lamxh,lamyh)’*Grad(X,Y))/dt - c2*(lamxh*X+lamyh*Y)/dt 62                      + mu*trace(DD(X,Y) ’*DD(Xh,Yh))/2 + lambda*div(X,Y)*div(Xh,Yh) 63                                          + penal*(lamx*lamxh+lamy*lamyh)); 65 varf ab([u,v,p],[lamxh,lamyh,Xh,Yh]) = 66           int2d(Ths,qft=qf9pT,mapu=[Xo,Yo])( 67                        c1*trace(Grad(lamxh,lamyh)’*(Grad(Xo,Yo)*Grad(u,v))) 68                      + c2*(lamxh*u+lamyh*v)); 70 varf ba([lamx,lamy,X,Y],[uh,vh,ph]) = 71           int2d(Ths,qft=qf9pT,mapt=[Xo,Yo])( 72                        c1*trace(Grad(lamx,lamy) ’*(Grad(Xo,Yo)*Grad(uh,vh))) 73                      + c2*(lamx*uh+lamy*vh)); 75 varf rhs1([u,v,p],[uh,vh,ph]) = 76           int2d(Thf)(-rhof*gravity*vh * 0 // 0=no gravity in the fluid 77                      + rhof*convect([uo,vo],-dt,uo)*uh/dt 78                      + rhof*convect([uo,vo],-dt,vo)*vh/dt) 79            + on(1,3,u=0,v=0) + on(2,4,u=0,v=0) ; 81 varf rhs2([lamx,lamy,X,Y],[lamxh,lamyh,Xh,Yh]) = 82           int2d(Ths)(-(rhos-rhof)*gravity*Yh + 2*(mu+lambda)*div(Xh,Yh) 83                      - c1*trace(Grad(lamxh,lamyh)’*Grad(Xo,Yo))/dt 84                      - c2*(lamxh*Xo+lamyh*Yo)/dt 85                      - (rhos-rhof)*((Xoo-2*Xo)*Xh+(Yoo-2*Yo)*Yh)/dt2); 87 for(int i=0;i<T/dt;i++){ 88  //       cout<<"time= "<<i*dt<<endl; 89                 real[int] RHS1 = rhs1(0,Zh); 90                 real[int] RHS2 = rhs2(0,Rh); 91                 matrix AA = aa(Zh,Zh); 92                 matrix AB = ab(Zh,Rh); 93                 matrix BA = ba(Rh,Zh); 94                 matrix BB = bb(Rh,Rh); 96                 matrix AABB = [ [AA,BA], [AB,BB] ]; 97                 set(AABB,solver=sparsesolver,master=-1); 98                 real[int] rhs = [RHS1, RHS2]; 99                 real[int] w=AABB^-1*rhs; 100                 Xoo=Xo; Yoo=Yo; Xoi=Xo; Yoi=Yo; 101                             [uo[],lamxo[]] = w; 102                 Thso = buildmesh(D(nn)); 103                                 Thf= buildmesh(a1(W*n/2)+a2(H*n)+a3(W*n)+a4(H*n)+D(nn)); 104                                 [uo,vo,po]=[uo,vo,po]; [lamxo,lamyo,Xo,Yo]=[lamxo,lamyo,Xo,Yo]; 105                                 cout<<i*dt<< " "<<int2d(Thso)(Yo-Yoo)/R1/R1/pi/dt<< " "<<int2d(Thso)(vo)/R1/R1/pi<< " area= "<<int2d(Thso)(1.)/R1/R1/pi<< " velocity "<<endl; 106                 uh=sqrt(uo*uo+vo*vo); 107                 plot(Thf, Thso, uh, value=1, fill=0, coef=100, cmm= "t="+i*dt+ "      Velocity"); 108 } 109 Thf = buildmesh(a1(W*n/2)+a2(H*n)+a3(W*n)+a4(H*n)+D(nn)); 110 [uo,vo,po]=[uo,vo,po]; 111 plot(vo, value=1, fill=0, coef=100, cmm= "t="+T+ " Pressure "); 112 fespace Bh(Thso,P1); 113 Bh s,sh; 114 solve bbc(s,sh)= int2d(Thso)(s*sh + 0.01*(dx(s)*dx(sh)+dy(s)*dy(sh))) 115 -int2d(Thso)(sh*(mu*dy(vo) + lambda*(dx(uo)+dy(vo)))); 116 plot(s);

Listing 5.2 Code for the rotating disk test

1 load  "MUMPS" 2 load  "pipe" 3 verbosity=0; 5 int n=20;   // higher for fine mesh 7 real R0=1, R1=2, R2=3,  gravity=0, ringvelocity=-3; 8 real  kappa=0.3,  /*E=1e4, mu=E/(1+kappa)/2 */ mu=1e2, lambda=2*kappa*mu/(1-2*kappa); 9 real rhof=1, rhos=10, nu=1, penal=1e-6; 10 real c1=10,c2=10,T=0.5, dt=0.005, dt2=dt*dt; 12 real delta=0.05; 13 border CF(t=0,2*pi){x=R2*cos(t); y=R2*sin(t);}  // fluid 14 border CS(t=0,2*pi){x=R1*cos(t); y=R1*sin(t);}   // solid 15 border CC(t=0,2*pi){x=R0*cos(t); y=R0*sin(t);}   // clamped 16 border C1(t=0,2*pi){x=(R1-delta)*cos(t); y=(R1-delta)*sin(t);}   // solid 17 border C2(t=0,2*pi){x=(R1-delta/2)*cos(t); y=(R1-delta/2)*sin(t);}   // solid 18 border C3(t=0,2*pi){x=(R1+delta/2)*cos(t); y=(R1+delta/2)*sin(t);}   // solid 19 border C4(t=0,2*pi){x=(R1+delta)*cos(t); y=(R1+delta)*sin(t);}   // solid 20 mesh Thf = buildmesh(CC(-10*n)  /*+C1(10*n)+C2(10*n)+C3(10*n) +C4(10*n)*/+CS(10*n)+CF(10*n)); 21 mesh Ths = buildmesh(CC(-10*n)+CS(10*n)); 22 mesh Thso=Ths; 23  // plot(Thf,Ths); 24 fespace Vh(Thf,P2); 25 fespace Qh(Thf,P1); 26 fespace Wh(Ths,P1); 27 fespace Lh(Ths,P1); 28 fespace Zh(Thf,[P2,P2,P1]); 29 fespace Rh(Ths,[P1,P1,P1,P1]); 31 Vh u,v,uh,vh; 32 Qh p,ph; 33 Wh  Xoo=x,Yoo=y; 34 Rh [lamx,lamy,X,Y],[lamxo,lamyo,Xo,Yo]=[0,0,x,y]; //x-(x-xc)/2,y+(y-yc)/2]; 35 Zh [uo,vo,po]=[0,0,0]; 37 macro div(u,v) ( dx(u)+dy(v) )  // EOM 38 macro Grad(u,v)[[dx(u),dy(u)],[dx(v),dy(v)]]  // EOM 39 macro DD(u,v)  [[2*dx(u),div(v,u)],[div(v,u),2*dy(v)]]  // EOM 41 varf aa([u,v,p],[uh,vh,ph]) = 42           int2d(Thf)(rhof*[u,v] ’*[uh,vh]/dt- div(uh,vh)*p -div(u,v)*ph 43                      + penal*p*ph + nu*trace(DD(uh,vh)’*DD(u,v))/2) 44           + on(CC,u=0,v=0) + on(CF,u=-ringvelocity*y/R2,v=ringvelocity*x/R2) ; 46 varf bb([lamx,lamy,X,Y],[lamxh,lamyh,Xh,Yh]) = 47           int2d(Ths)((rhos-rhof)*(X*Xh+Y*Yh)/dt2 48                      - c1*trace(Grad(lamx,lamy) ’*Grad(Xh,Yh)) - c2*(lamx*Xh+lamy*Yh) 49                      - c1*trace(Grad(lamxh,lamyh)’*Grad(X,Y))/dt - c2*(lamxh*X+lamyh*Y)/dt 50                      + mu*trace(DD(X,Y) ’*DD(Xh,Yh))/2 + lambda*div(X,Y)*div(Xh,Yh) 51                                          + penal*(lamx*lamxh+lamy*lamyh)); 53 varf ab([u,v,p],[lamxh,lamyh,Xh,Yh]) = 54           int2d(Ths,qft=qf9pT,mapu=[Xo,Yo])( 55                        c1*trace(Grad(lamxh,lamyh)’*(Grad(Xo,Yo)*Grad(u,v))) 56                      + c2*(lamxh*u+lamyh*v)); 58 varf ba([lamx,lamy,X,Y],[uh,vh,ph]) = 59           int2d(Ths,qft=qf9pT,mapt=[Xo,Yo])( 60                        c1*trace(Grad(lamx,lamy) ’*(Grad(Xo,Yo)*Grad(uh,vh))) 61                      + c2*(lamx*uh+lamy*vh)); 63 varf rhs1([u,v,p],[uh,vh,ph]) = 64           int2d(Thf)( rhof*convect([uo,vo],-dt,uo)*uh/dt 65                      + rhof*convect([uo,vo],-dt,vo)*vh/dt) 66            + on(CC,u=0,v=0) + on(CF,u=-ringvelocity*y/R2,v=ringvelocity*x/R2) ; 68 varf rhs2([lamx,lamy,X,Y],[lamxh,lamyh,Xh,Yh]) = 69           int2d(Ths)( 2*(mu+lambda)*div(Xh,Yh) 70                      - c1*trace(Grad(lamxh,lamyh)’*Grad(Xo,Yo))/dt 71                      - c2*(lamxh*Xo+lamyh*Yo)/dt 72                      - (rhos-rhof)*((Xoo-2*Xo)*Xh+(Yoo-2*Yo)*Yh)/dt2); 74  //////////////////////////////////////////////////////////// 75  //// semi-analytic solution by solving a 1d problem ///// 76 mesh Th=square(100,1,[R0+(R2-R0)*x,0.1*y]); 77 fespace WWh(Th,P2,periodic=[[1,x],[3,x]]); 78 fespace W0(Th,P1dc); 79 WWh d=0,wo,wh,wold=0; 80 W0 nnu=nu*(x>R1)+mu*dt*(x<=R1), Rho=rhof*(x>R1)+(rhos-rhof)*(x<=R1); 81 problem AA1d(wo,wh) = int2d(Th)(Rho*x*wo*wh/dt+x*nnu*dx(wo)*dx(wh) ) 82                         + int2d(Th)( -Rho*x*wold*wh/dt + mu*(x<=R1)*x*dx(d)*dx(wh) ) 83                         +on(2,wo=ringvelocity)+on(4,wo=0); // this is the one-d axisymmetric problem 84  ////////////////////////////////////////// 86 pstream  pgnuplot( "gnuplot" );   // prepare gnuplot ////////////// 87 int NT=T/dt,J=40; 88 real l2error=0, dr = (R2-R0)/(J-1); 90  /////////////////////////////// time loop ///////////////////////// 91 for(int i=0;i<NT;i++){ 92  //       cout<<"time= "<<i*dt<<endl; 93                 real[int] RHS1 = rhs1(0,Zh); 94                 real[int] RHS2 = rhs2(0,Rh); 95                 matrix AA = aa(Zh,Zh); 96                 matrix AB = ab(Zh,Rh); 97                 matrix BA = ba(Rh,Zh); 98                 matrix BB = bb(Rh,Rh); 100                 matrix AABB = [ [AA,BA], [AB,BB] ]; 101                 set(AABB,solver=sparsesolver,master=-1); 102                 real[int] rhs = [RHS1, RHS2]; 103                 real[int] w=AABB^-1*rhs; 104                 Xoo=Xo; Yoo=Yo; 105                             [uo[],lamxo[]] = w; 106  //                              cout<<i*dt;<<" "<<int2d(Thso)(Yo-Yoo)/R1/R1/pi/dt<<" "<<int2d(Thso)(vo)/R1/R1/pi<<" area= "<<int2d(Thso)(1.)/R1/R1/pi<<" velocity "<<endl; 107  //                uh=sqrt(uo*uo+vo*vo); 108                  ///////////////// for error plot /////////////////////// 109                 AA1d; 110                 d=d+wo*dt; 111                 wold=wo;   // this is for the one-d axisymmetric problem 112                 ofstream f( "aux.gp"); 113                 for(int j=0;j<J;j++) { 114                         f << j*dr << "   " << vo(R0+j*dr,0)<< "  "<< wo(R0+j*dr,0.05)<< endl; 115                         l2error += (vo(R0+j*dr,0)-wo(R0+j*dr,0.05))^2*dt; 116                 } 117                 pgnuplot <<  " plot [0:2][-3:0.51]’aux.gp’ u 1:2 w l,’aux.gp’ u 1:3 w l"<< endl; 118                 cout<<i*dt<< "  "<<sqrt(l2error)/T<<endl; 119                 flush(pgnuplot); 120 } 121 plot(Ths,Thf,[uo,vo],fill=1, coef=0.1, cmm= "t="+T, wait=1)      ; 123 for(int j=0;j<J;j++) 124  cout<< j*dr<< "  "<< vo(R0+j*dr,0)<< "  "<<wo(R0+j*dr,0.05)<< "  "<<vo(R0+j*dr,0)-wo(R0+j*dr,0.05) <<endl; 125   // copy past the numbers in a file "results.txt", call gnuplot and do in the gnuplot terminal window: 126   // plot"results.txt"using 1:2,"results.txt"using 1:3 w l

Listing 5.3 Code for FSI-3 test

1 verbosity=0; 3 int n=2, m=2*n, NN=500*m;   // higher for fine mesh 5 real rhof=1, rhos=1, nu=0.001, penal=1e-9; 6  // rho, mu, rescaled : divided by 1e6 7 real  kappa=0.4, E=1e6, mu=2e3, lambda=2*kappa*mu/(1-2*kappa); 8 real Ubar=2, gravity=0*981; 9 real T=6, dt=T/NN, dt2=dt*dt; 10 real c1=1, c2=1;  // Lagrange multiplier constants: H1 -> 1,1, L2 -> 0,1 12  // mesh Thf=square(10*n,H*n,[x,H*y]); // fluid + solid domain 14 int la1=10, la2=11; 15 real cx0 = 0.2, cy0 = 0.2;  // center of cyl. 16 real r=0.05, H=0.41, L=2.5;  // radius of cylinder, size of domain 17 real ll=0.35, h2=0.01; //flagella length and half thickness 18 real la=asin(h2/r), x0=sqrt(r*r-h2*h2); 20 border fr1(t=0,L){x=t; y=0; label=1;}  // outer box begins 21 border fr2(t=0,H){x=L; y=t; label=2;} 22 border fr3(t=L,0){x=t; y=H; label=1;} 23 border fr4(t=H,0){x=0; y=t; label=3;}  // outer box ends 24 border fr5(t=la,2*pi-la){x=cx0+r*cos(-t); y=cy0+r*sin(-t); label=4;} 25 border br1(t=-la,la){x=cx0+r*cos(-t); y=cy0+r*sin(-t); label=4;}  // flag begins 26 border br2(t=0,ll){x=cx0+x0+t; y=cy0-h2;label=la1;} 27 border br3(t=-h2,h2){x=x0+cx0+ll; y=cy0+t;label=la1;} 28 border br4(t=ll,0){x=cx0+x0+t; y=cy0+h2;label=la1;}               // flag ends 30 mesh Thf=buildmesh(fr1(20*m)+fr2(3.25*m)+fr3(20*m)+fr4(4*m)+fr5(12*m) + br1(m)+br2(12*m)+br3(2*m)+br4(12*m)); 32 mesh Thsi = buildmesh(br1(m)+br2(12*m)+br3(m)+br4(12*m));  // Initial solid domain 34 fespace Whi(Thsi,P1); 35 Whi Xoi=x,Yoi=y; 36 real[int] xx(25*m+1), yy(25*m+1); 37 int[int] nn(25*m); 38 for(int i=0;i<=25*m;i++){ 39         if(i<=12*m){ real t=ll*i/(12.0*m); xx[i]=cx0+x0+t; yy[i]=cy0-h2; } 40                 else if(i<=13*m){real t=2*h2*(i-12.0*m)/m-h2; xx[i]=x0+cx0+ll; yy[i]=cy0+t;} 41                 else { real t=ll-ll*(i-13*m)/(12.0*m); xx[i]=cx0+x0+t; yy[i]=cy0+h2; } 42                 if(i<25*m) nn[i]=2; 43         } 44 border D(t=0,1;i){ 45         int ii = (i+1)%(25*m+1); real t1 = 1-t; real x1 = xx[i]*t1 + xx[ii]*t; 46         real y2 = yy[i]*t1 + yy[ii]*t; x= Xoi(x1,y2); y=Yoi(x1,y2); 47         label=la1; 48 } 49 plot(br1(m) + D(nn)); 50 mesh Ths = buildmesh(br1(m) + D(nn)); 51 int nbA; 52 real xnear=x0+cx0+ll+3*h2, ynear=cy0-3*h2, distmin=10; 53 plot(Ths); 55 mesh Thso=Ths; 56  //mesh Thf= buildmesh(a1(W*n/2)+a2(H*n)+a3(W*n)+a4(H*n)+D(nn)); 57  //plot(a1(10*n)+a2(H*n)+a3(10*n)+a4(H*n)+D(nn)); 58 plot(Thf,Thso, cmm= "Initial configuration"); 60 fespace Vh(Thf,P1b);   // velocity space 61 fespace Qh(Thf,P1);   // pressure space 62 fespace Wh(Ths,P1b);   // Lagrangian coordinates X,Y space 63 fespace Lh(Ths,P1);   // Lagrangian multiplier space 64 fespace Zh(Thf,[P1b,P1b,P1]);  // fluid space 65 fespace Rh(Ths,[P1,P1,P1b,P1b]); // solid space 67 Vh u,v,uh,vh; 68 Qh p,ph; 69 Wh  Xoo=x,Yoo= y;  // the X,Y are now the displacements 70 Rh [lamx,lamy,X,Y],[lamxo,lamyo,Xo,Yo]=[0,0,x,y]; //x-(x-xc)/2,y+(y-yc)/2]; 71 Zh [uo,vo,po]=[0,0,0]; 73 macro div(u,v) ( dx(u)+dy(v) )  // EOM 74 macro Grad(u,v)[[dx(u),dy(u)],[dx(v),dy(v)]]  // EOM 75 macro DD(u,v)  [[2*dx(u),div(v,u)],[div(v,u),2*dy(v)]]  // EOM 77 varf aa([u,v,p],[uh,vh,ph]) = 78           int2d(Thf)(rhof*[u,v] ’*[uh,vh]/dt- div(uh,vh)*p -div(u,v)*ph 79                      + penal*p*ph + nu*trace(DD(uh,vh)’*DD(u,v))/2) 80           + on(1,4, u=0,v=0) +  on(3,u=Ubar*y*(H-y)*6/H/H,v=0) ; 82 varf bb([lamx,lamy,X,Y],[lamxh,lamyh,Xh,Yh]) = 83           int2d(Ths)((rhos-rhof)*(X*Xh+Y*Yh)/dt2 84                      - c1*trace(Grad(lamx,lamy) ’*Grad(Xh,Yh)) - c2*(lamx*Xh+lamy*Yh) 85                      - c1*trace(Grad(lamxh,lamyh)’*Grad(X,Y))/dt - c2*(lamxh*X+lamyh*Y)/dt 86                      + mu*trace(DD(X,Y) ’*DD(Xh,Yh))/2 + lambda*div(X,Y)*div(Xh,Yh) 87                                          + penal*(lamx*lamxh+lamy*lamyh)) 88                                          + on(4,X=x,Y=y); 90 varf ab([u,v,p],[lamxh,lamyh,Xh,Yh]) = 91           int2d(Ths,qft=qf9pT,mapu=[Xo,Yo])( 92                        c1*trace(Grad(lamxh,lamyh)’*(Grad(Xo,Yo)*Grad(u,v))) 93                      + c2*(lamxh*u+lamyh*v)); 95 varf ba([lamx,lamy,X,Y],[uh,vh,ph]) = 96           int2d(Ths,qft=qf9pT,mapt=[Xo,Yo])( 97                        c1*trace(Grad(lamx,lamy) ’*(Grad(Xo,Yo)*Grad(uh,vh))) 98                      + c2*(lamx*uh+lamy*vh)); 100 varf rhs1([u,v,p],[uh,vh,ph]) = 101           int2d(Thf)(-rhof*gravity*vh * 0 // 0=no gravity in the fluid 102                      + rhof*convect([uo,vo],-dt,uo)*uh/dt 103                      + rhof*convect([uo,vo],-dt,vo)*vh/dt) 104            + on(1,4, u=0,v=0) +  on(3,u=Ubar*y*(H-y)*6/H/H,v=0) ; 106 varf rhs2([lamx,lamy,X,Y],[lamxh,lamyh,Xh,Yh]) = 107           int2d(Ths)(-(rhos-rhof)*gravity*Yh + 2*(mu+lambda)*div(Xh,Yh) 108                      - c1*trace(Grad(lamxh,lamyh)’*Grad(Xo,Yo))/dt 109                      - c2*(lamxh*Xo+lamyh*Yo)/dt 110                      - (rhos-rhof)*((Xoo-2*Xo)*Xh+(Yoo-2*Yo)*Yh)/dt2) 111                                          + on(4,X=x,Y=y); 113 real t0=0, MMCL=-100, MCL=-100,maxCL=-100,minCL=100; 114 for(int i=0;i<T/dt;i++){ 115  //       cout<<"time= "<<i*dt<<endl; 116                 real[int] RHS1 = rhs1(0,Zh); 117                 real[int] RHS2 = rhs2(0,Rh); 118                 matrix AA = aa(Zh,Zh); 119                 matrix AB = ab(Zh,Rh); 120                 matrix BA = ba(Rh,Zh); 121                 matrix BB = bb(Rh,Rh); 123                 matrix AABB = [ [AA,BA], [AB,BB] ]; 124                 set(AABB,solver=sparsesolver,master=-1); 125                 real[int] rhs = [RHS1, RHS2]; 126                 real[int] w=AABB^-1*rhs; 127                 Xoo=Xo; Yoo=Yo; 128                                 Xoi=Xo; Yoi=Yo; 129                             [uo[],lamxo[]] = w; 130                 Thso = buildmesh(br1(m) + D(nn)); 131                                 Thf= buildmesh(fr1(20*m)+fr2(3.25*m)+fr3(20*m)+fr4(4*m)+fr5(12*m) + br1(m) + D(nn)); 132  //                              plot(br1(m) + D(nn)); 133                                 [uo,vo,po]=[uo,vo,po]; [lamxo,lamyo,Xo,Yo]=[lamxo,lamyo,Xo,Yo]; 134                 uh=sqrt(uo*uo+vo*vo); 135                 plot(Thf, Thso, uh, value=1, fill=1, coef=100, cmm= "t="+i*dt+ "      Velocity"); 136                                 int nbA; 137                                 real xnear=x0+cx0+ll+3*h2, ynear=cy0-3*h2, distmin=10; 138                                 for(int k=0;k<Ths.nv;k++) 139                                                 if((Thso(k).x-xnear)^2 + (Thso(k).y-ynear)^2 < distmin) 140                                                         {distmin=(Thso(k).x-xnear)^2 + (Thso(k).y-ynear)^2; nbA=k;} 141                             real CL=Thso(nbA).y; 142                             if(minCL>CL) minCL=CL; 143                             if(MMCL<MCL && CL<MCL && MCL>0.2 && MMCL>0.2) { 144                                         cout<< "ft= "<<1./(i*dt-t0)<< " minCL= "<<minCL 145                                         << " maxCL= "<<MCL<< " (max-min)/2= "<< (MCL-minCL)/2<< endl; 146                                         MCL=-100; MMCL=-100; 147                                         t0=i*dt; minCL=10; 148                                 } 149                               MMCL=MCL; MCL=CL; 150                                 cout<<i*dt<< "  "<<Thso(nbA).x<< " "<<Thso(nbA).y<< "  " << int2d(Thso)(1.)<< endl; 151 }

Appendix 2: Some Comments on the Codes

We assume that the reader has a basic experience with FreeFem++. The codes are then pretty straightforward to be understood. Given the fluid mesh Thf, for instance, the definition of the finite element spaces for the approximation of the Navier–Stokes equation is performed with the following lines

fespace Vh(Thf,P1b); fespace Qh(Thf,P1);

in the case of the MINI element [3], or with the following lines

fespace Vh(Thf,P2); fespace Qh(Thf,P1);

if the user prefers Taylor–Hood element. Analogous definition can be used for the two finite element spaces based on the solid mesh Ths, for instance,

fespace Wh(Ths,P1); fespace Lh(Ths,P1);

Like in all fluid-structure interaction problems, one of the crucial parts of the code consists in the evaluation of the terms involving an interaction between the fluid and solid meshes. This occurs in two places of our code: in the assembly of the bilinear form ab and of ba. Let us look in more detail at the assembly of ab, for instance. The bilinear form to be approximated is

and the crucial terms involve u(X) where the finite element function u, defined on the mesh Thf has to be evaluated on X which is defined on the mesh Ths. This interpolation problem is naturally solved by using the option mapu in the evaluation of the integral as follows:

varf ab([u,v,p],[lamxh,lamyh,Xh,Yh]) =     int2d(Ths,qft=qf9pT,mapu=[Xo,Yo])(         c1∗trace(Grad(lamxh,lamyh)'            ∗(Grad(Xo,Yo)∗Grad(u,v)))         + c2∗(lamxh∗u+lamyh∗v));

Analogously, when the mapping between the meshes involves the test function, as in the case of the definition of ba, the option mapt comes into play. In this particular case, the bilinear form

can be described with the following code instruction

varf ba([lamx,lamy,X,Y],[uh,vh,ph]) =     int2d(Ths,qft=qf9pT,mapt=[Xo ,Yo])(         c1∗trace(Grad(lamx,lamy)'            ∗(Grad(Xo,Yo)∗Grad(uh,vh)))         + c2∗(lamx∗uh+lamy∗vh));

Rights and permissions

Reprints and permissions

Copyright information

© 2018 Springer Nature Switzerland AG

About this chapter

Check for updates. Verify currency and authenticity via CrossMark

Cite this chapter

Boffi, D., Hecht, F., Pironneau, O. (2018). Distributed Lagrange Multiplier for Fluid-Structure Interactions. In: Di Pietro, D., Ern, A., Formaggia, L. (eds) Numerical Methods for PDEs. SEMA SIMAI Springer Series, vol 15. Springer, Cham. https://doi.org/10.1007/978-3-319-94676-4_5

Download citation

Publish with us

Policies and ethics