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.
Access provided by CONRICYT-eBooks. Download chapter PDF
Similar content being viewed by others
Keywords
- Distributed Lagrange Multiplier
- FreeFem
- Fluid-structure Interaction Problems
- Fictitious Domain Technique
- Fluid Mesh
These keywords were added by machine and not by the authors. This process is experimental and the keywords may be updated as the learning algorithm improves.
5.1 Introduction
The use of a distributed Lagrange multiplier for the modeling and approximation of interface problems has a long history within approaches based on fictitious domain techniques [6].
The applications of this methodology for fluid-structure interaction problems has been rediscovered and discussed in recent research [1, 4] originating from the immersed boundary method [2, 9]. The theoretical properties of this approach are quite good, showing unconditional stability for a semi-implicit time discretization and inf-sup stability for the global saddle point problem under suitable conditions on the underlying meshes. Our formulation and some of the main results about it will be summarized in Sect. 5.2.
In this paper we present a series of numerical tests performed with the help of FreeFem++ [7]. All results are collected in Sect. 5.3. In all tests, the agreement with the analytical solution (if known) or with solutions present in the literature is quite good.
One of the main difficulties in the implementation of any fluid-structure interaction model, consists in the appropriate treatment of the exchange of information between fluid and solid. In our formulation the fluid mesh is fixed, while the solid mesh is defined on a reference configuration and mapped to the actual solid domain via the (unknown) transformation which defines the position of the body. It turns out that some terms in our variational formulation need to combine quantities defined on the fluid and solid meshes. Actually, FreeFem++ has a built in function that allows the computation of such terms. Our codes are listed in Appendix 1 and some comments are provided in Appendix 2.
5.2 Problem Setting
The model introduced in [4] can deal with co-dimension zero (thick) or co-dimension one (thin) bodies immersed in a fluid of two or three space dimensions. Our numerical tests involve thick bodies in two space dimensions; we recall the related formulation.
Let Ω be a bounded domain in \(\mathbb {R}^2\) with Lipschitz continuous boundary. We assume that the domain is partitioned into a fluid part Ω f and a solid part Ω s (both subdomains are time dependent). The solid domain Ω s is the image of a reference domain . More precisely, the mapping associates to each point its image x = X(s, t) ∈ Ω s at time t. We denote by ρ f and ρ s the fluid and solid densities, respectively, by ν the fluid viscosity, and by λ and μ the Lamé constants.
The problem considered in [4] is the following one: given an initial velocity \({\mathbf {u}}_0\in (H^1_0(\varOmega ))^2\), an initial body position , find velocity and pressure \(({\mathbf {u}}(t),p(t))\in (H^1_0(\varOmega ))^2\times L^2_0(\varOmega )\), body position , and a Lagrange multiplier λ(t) ∈ Λ such that for almost every t ∈ ]0, T[ is holds
where \({{\mathbb {D}_t}}\) is the total derivative and D is the symmetric gradient.
The constants c 1, c 2 and the space Λ are crucial for the definition of the model and the subsequent numerical scheme: in our computations we consider both c 1 and c 2 positive and different from zero (H 1-based Lagrange multiplier), so that the space Λ is .
5.2.1 Numerical Approximation
The time semi-discretization of Problem (5.1) is constructed as follows: in the first equation the total derivative is approximated by the Galerkin-characteristic method (see [10]); the second derivative ∂ tt X(t) in the second equation is approximated by (X n+1 − 2X n + X n−1)∕δt 2; ∂ t X is approximated by (X n+1 −X n)∕δt; all other quantities are evaluated implicitly at time n + 1 with the following exception. Clearly, there is a problem when a term involving \(\hat {\mathbf {u}}({\mathbf {X}})\) has to be integrated on . Treating this term fully implicitly would imply the use of the mapping X n+1 which is not yet available; for this reason we use a semi-implicit scheme where \(\hat {\mathbf {u}}({\mathbf {X}}^n)\) is used, instead.
In [4, Prop. 3] it has been shown that the resulting semi-discrete scheme is unconditionally stable with respect to the time step δt. The proof is based on a discrete energy estimate which is analogous to the stability estimate for the continuous problem:
where the energy E is defined in terms of the energy density \(W(\mathbb {F})\) (\(\mathbb {F}\) being the deformation gradient)
The numerical approximation of Problem (5.1) is based on a set of four finite element spaces: \(V_h\subset (H^1_0(\varOmega ))^2\) and \(Q_h\subset L^2_0(\varOmega )\) are inf-sup stable finite element spaces, while and Λ h ⊂ Λ are finite elements defined in the solid domain. More precisely, V h and Q h are finite elements defined according to a triangulation of Ω, while S h and Λ h are finite elements defined on a mesh of the reference solid configuration .
5.3 Numerical Tests
In all tests the solid is hyper-elastic with Young modulus E, Poisson ratio κ and density ρ s. The shear modulus is then given by μ = E∕(1 + κ)∕2.
The fluid is Newtonian incompressible with density ρ f and viscosity ν.
5.3.1 Disk Falling in a Liquid
A disk of diameter d is at rest initially centred at x c = W∕2, y c = H − h in a rectangular channel of width W and height H. Only the disk is subject to gravity g, not the fluid. No slip conditions are applied on the walls of the channel.
This test was proposed by Zhao et al. in [12] and more recently by Wang et al. in [11]. Here we chose Wang’s values for the parameters:
The asymptotic vertical velocity is known to be − 0.3567. Figure 5.1 shows the evolution of the vertical velocity versus time for four meshes: a coarse mesh with 1182 vertices, a middle mesh with 4693 vertices and a fine mesh with 18,661 vertices. The corresponding time steps are 0.02, 0.01, 0.005.
For these three cases the fluid mesh is modified at each time step to include the fluid-structure interface as an interline curve made of edges of the triangulation. Computation is also made on a fourth mesh with 4693 and the initial fluid-solid interface at time zero but not changed with time. On this fourth mesh precision degrades with time, probably due to mesh interpolations. On the three previous body fitted mesh there is convergence to a limit curve, but the asymptotic value seems to be − 0.3788 rather than − 0.3567. It could be due to the fact that the fluid model is extended in the solid leading to an error proportional to ρ s − ρ f. But it could also be the effect of interpolation needed to computed variables earlier defined on the mesh before motion. We are currently intersecting meshes to reduce this interpolation error and preliminary tests (to be published later) point to the direction of a more accurate falling velocity. On the other hand, mass is remarkably preserved as shown on Fig. 5.1-right.
A pressure map at t = 0.7 is given on Fig. 5.2-left. Next the same simulation is done with a very soft material having μ = 10. The shape of the solid at t = 0.7 is given with a color map of the yy component of the stress on Fig. 5.2-right. The computing time for this last test is 434” on a Core i7-2.5GHz on a single core.
For these two simulations the influence of the coefficients c 1 and c 2 are small, as long as c 2 is not zero. Here both are set at 1. The influence of the degree of the finite element spaces is also surprisingly small. Both the P2/P1 element for velocity pressure or the P1-bubble/P1 element gave the same results. Changing P1 into P2 for the Lagrangian coordinates also didn’t make a difference. It seems that the precision of the method is entirely driven by the quadrature formula used for the mixed integrals involving a function on the fluid mesh times a function on the transformed solid mesh.
Some integrals in the variational formulation involve piecewise polynomial functions defined on different meshes. We have developed a special quadrature formula in FreeFem++ (see [7]) to handle them. For instance let u be defined on mesh \(T^u_h\) and v be defined on mesh \(T^v_h\) obtained from \(T^u_h\) by convecting the vertices \(q^i\in T^u_h\) with X, namely X(q i) is a vertex of \(T^v_h\). Then for a triangle T of \(T^v_h\) the integral on T of u ∘ X ⋅ v is approximated by \(\sum _{j=1}^J u(X(\xi _j))v(\xi _j)\omega _j\) where ξ j, ω j are a valid set of quadrature points and coefficients for a quadrature on T (shown in the FreeFem++ code by a parameter in the integral like int2d( Ths,qft=qf9pT,mapu=[Xo,Yo]).
5.3.2 Validation with a Rotating Disk
The purpose of this test is to compare the numerical solution with a semi-analytical solution which can be computed to any desired accuracy.
A cylinder contains a fixed rigid cylindrical rod in its center, a cylindrical layer of hyperelastic material around the rod and the rest is filled with a fluid (see Fig. 5.3). First the system is at rest and then a constant rotation is given to the outer cylinder. This cause the fluid to rotate with an angular velocity which depends on the distance r to the main axis; in turn, because the friction of the fluid at the interface the hyperelastic material will be dragged into a angular velocity ω which is also only a function of r and time . Due to elasticity ω will oscillate with time until numerical dissipation and fluid viscosity damps it.
In a two dimensional cut perpendicular to the main axis, the velocities and displacements are two dimensional as well. Hence the geometry is a ring of inner and outer radii, R 0 and R 1, with hyperelastic material between R 0 and R and fluid between R and R 1. Because of axial symmetry, R is constant, so the geometry does not change.
In this test R 0 = 3, R = 4, R 1 = 5. The solid is an hyperelastic material with μ = 100 and λ = 2κμ∕(1 − 2κ) with κ = 0.3 and ρ s = 10. The Newtonian fluid has ν = 1, ρ f = 1. The velocity of the outer cylinder has magnitude 3. As everything is axisymmetric the computation can be done in polar coordinates r, θ, and the fluid-solid system reduces to
with ρ = ρ s 1 r≤R + ρ f 1 r>R, ξ s = μ 1 r≤R, ξ f = ν 1 r>R, and with d(r, 0) = 0.
In all 2d computations c 1 = c 2 = 10 and δt = 0.005. We have verified that a smaller time step does not improve the precision.
Comparison between this one dimensional approach and the numerical solution of system (5.1) is given on Fig. 5.3—right, at T = 0.5 and a coarse mesh with 505 vertices. Then the same is computed on a finer mesh having 1986 vertices and finally with a mesh with 7433 vertices. Results are displayed on Fig. 5.4.
This test has two qualities: (a) the exact solution is easy to compute to any precision; (b) the geometry does not change and quadrature errors are due only to quadrature for integrals involving functions on the same domain but with two different triangulations.
5.3.2.1 Flow Past a Cylinder with a Flagella Attached
This test is known as FLUSTRUK-FSI-3 in [5]. The geometry is shown on Fig. 5.5. The inflow velocity is \(\bar U=2\), μ = 2106 and ρ s = ρ f. After some time a Karman-Vortex alley develops and the flagella beats accordingly. Results are shown on Figs. 5.5 and 5.6 with a mesh of 9692 vertices and a time step size of 0.0015; the first one displays a snapshot of the velocity vector norms and the second the y-coordinate versus time of the top right corner of the flagella.
These numerical results compare reasonably well with those of [5]. The frequency is 5.6 compared to 5.04 and the maximum amplitude 0.018 compared with 0.032. Amplitude is very sensitive to the method (see [8]).
References
Boffi, D., Gastaldi, L.: A fictitious domain approach with Lagrange multiplier for fluid-structure interactions. Numer. Math. 135(3), 711–732 (2017)
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)
Boffi, D., Brezzi, F., Fortin, M.: Mixed Finite Element Methods and Applications. Springer Series in Computational Mathematics, vol. 44. Springer, New York (2013)
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)
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)
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)
Hecht, F.: New development in FreeFem++. J. Numer. Math. 20(3–4), 251–265 (2012)
Hecht, F., Pironneau, O.: An energy stable monolithic Eulerian fluid-structure finite element method. Int. J. Numer. Methods Fluids 85(7), 430–446 (2017)
Peskin, C.S.: The immersed boundary method. Acta Numer. 11, 479–517 (2002)
Pironneau, O.: On the transport-diffusion algorithm and its applications to the Navier-Stokes equations. Numer. Math. 38(3), 309–332 (1981/82)
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)
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)
Author information
Authors and Affiliations
Corresponding author
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
Copyright information
© 2018 Springer Nature Switzerland AG
About this chapter
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
DOI: https://doi.org/10.1007/978-3-319-94676-4_5
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-319-94675-7
Online ISBN: 978-3-319-94676-4
eBook Packages: Mathematics and StatisticsMathematics and Statistics (R0)