Uzawa conjugate gradient method for the Stokes problem: Matlab implementation with P1-iso-P2/P1 finite element Jonas Koko LIMOS, Université Blaise Pascal – CNRS UMR 6158 ISIMA, Campus des Cézeaux – BP 10125, 63173 Aubière cedex, France [email protected] Abstract We propose a detailed Matlab implementation of the Uzawa Conjugate gradient algorithm for the generalized Stokes problem with a P1 -iso-P2 /P1 finite element discretization. Vectorized Matlab functions for assembling mass, Laplacian and divergence matrices, required by the Uzawa algorithm, are provided. Keywords: Stokes equations, Uzawa method, finite element, Matlab. AMS subject classification: 65N30, 65K10, 76D07 1 Introduction This paper presents a detailed Matlab implementation of the (preconditioned) Uzawa conjugate gradient algorithm for the generalized Stokes problem using the P 1 -iso-P2 /P1 finite element. The Uzawa scheme is a decomposition coordination method with coordination by the Lagrange multiplier (the pressure). The decomposition step reduces to uncoupled scalar Poisson equations. We use the preconditioner advocated by Cahouet and Chabard [3], well-suited for generalized Stokes problems with high parameters ratio. Then in both decomposition and coordination steps, the linear systems solved are equivalent to scalar Poisson equations. The finite element spaces P1 -iso-P2 /P1 consist of two superimposed P1 meshes Th (the fine mesh) and T2h (the coarser mesh) in which T2h is twice coarser than Th . Consequently, the same assembling functions can be used for velocity and pressure matrices. At a first sight, it seems difficult to use a vectorization techniques for this element for which the number of unknowns at each node depends on the node position, whether at a vertex or at a mid-edge. But with a suitable data representation, the calculations can be carried out using vectorization techniques. Matlab is a matrix language, that is, Matlab is designed for matrix and vector operations. For best performance in large scale problems, one should take advantage of this. That is why all matrix assembling functions proposed are vectorized. Vectorization means that there is no loop over triangles nor nodes. Our implementation required only Matlab basic distribution functions and can be easily modified and refined. The paper is organized as follows. The generalized Stokes problem is presented in Section 2 followed by the finite element discretization in Section 3. In Section 4 we 1 2 2 THE STOKES PROBLEM detail the data representation of the P 1 -iso-P2 /P1 triangulation. The Uzawa conjugate gradient algorithm is presented in Section 5. Matlab assembling functions for matrices and the right-hand side are presented in Section 6 and 7. In Section 8 we present Matlab implementation of the Uzawa conjugate gradient algorithm. Some numerical experiments are carried out in Section 9. In the appendix, we give Matlab programs used for numerical experiments and a Matlab function which generates a P 1 -iso-P2 /P1 mesh from a P1 mesh. 2 The Stokes problem Let Ω be a two-dimensional domain with Lipschitz-continuous boundary Γ = ∂Ω. Consider in Ω the Stokes problem αu − ν∆u + ∇p = f, in Ω, (2.1) ∇ · u = 0, in Ω, (2.2) Γ u = u , on Γ. (2.3) u = (u1 (x), u2 (x)) is the velocity vector, p = p(x) is the pressure and f = (f 1 (x), f2 (x)) is the field of external forces. In (2.1), α ≥ 0 is an arbitrary constant. If α = 0, (2.1)-(2.2) turn to be the classic Stokes problem. The constant ν ≥ 0 is the kinematic viscosity and if ν = 0, (2.1)-(2.2) turn to be L2 projection encountered in time discretization of NavierStokes equations (see e.g. [4, 5]). In unsteady Navier-Stokes calculations, α ≡ (δt) −1 , where δt is the time step. Hence, if δt << 1, then α >> 1. We need functional spaces ViD = v ∈ H 1 (Ω) : v = uΓ on Γ , V D = V1D × V2D , Z 1 2 Vi = H0 (Ω), V = V1 × V2 , P = p ∈ L (Ω) : p dx = 0 , Ω and bilinear forms ai (ui , vi ) = α(ui , vi )Ω + ν(∇ui , ∇vi )Ω , i = 1, 2 a(u, v) = 2 X ai (ui , vi ). i=1 The variational formulation of the Stokes problem (2.1)-(2.3) is as follows: Find (u, p) ∈ V D × P such that: a(u, v) − (p, ∇ · v)Ω = (f, v)Ω , −(q, ∇ · u)Ω = 0, 3 ∀v ∈ V, ∀q ∈ P. (2.4) (2.5) Finite element discretization We consider Th a finite element triangulation of Ω and T 2h a triangulation twice coarser. In practice, T2h is constructed first and then Th by joining the midpoints of the edges of T2h as shown in Fig. 1. 3 3 FINITE ELEMENT DISCRETIZATION A A A A A A A A A A A A A A Figure 1: Subdivision of a triangle of T 2h For the discrete velocity-pressure spaces, we use the P 1 -iso-P2 /P1 element. These spaces are well-known to satisfy the discrete Babuska-Brezzi inf-sup condition. Let P 1 be the space of polynomials in two variables of degree ≤ 1. We define the following finite element spaces which approximate V i , V , ViD , V D and P respectively: Vih = vh ∈ C 0 (Ωh ), vh |T ∈ P1 , ∀T ∈ Th , vh |Γ = 0 , Vh = V1h × V2h D D VihD = vh ∈ C 0 (Ωh ), vh |T ∈ P1 , ∀T ∈ Th , vh |Γ = uΓih , VhD = V1h × V2h Z 0 ph dx = 0 , Ph = ph ∈ C (Ωh ), ph |T ∈ P1 , ∀T ∈ T2h , Ωh In VhD , uΓh is the approximate boundary condition verifying the flux condition Z uΓh · ndΓ = 0. Γ The discrete version of equations (2.4)-(2.5) is Find (uh , ph ) ∈ VhD × Ph such that: a(uh , vh ) − (ph , ∇ · vh ) = (f, vh ), −(qh , ∇ · uh ) = 0, ∀vh ∈ Vh , ∀qh ∈ Ph . On the fine mesh Th , this results on the algebraic system of the form f1 u1 A1 0 −B1t A2 −B2t u2 = f2 , 0 0 p −B1 −B2 0 (3.1) (3.2) (3.3) where Ai = αMi + νKi , i = 1, 2 with Mi the mass matrix and Ki the stiffness matrix. Matrices A1 and A2 are symmetric, positive definite (after incorporating the boundary conditions). With a suitable data representation of the triangulation T h , the vector p is split as follows " # p2h p= ph where p2h consists of all values of the pressure at the coarse mesh, and p h those at the other nodes. 4 4 4 DATA REPRESENTATION OF THE TRIANGULATION Data representation of the triangulation We store node coordinates and triangles vertices, of the fine mesh T h , in two arrays p(1:nph,1:2) and th(1:nth,1:3), where nph is the number of nodes and nth the number of triangles. Since Th is obtained by bisection of edges of the coarse mesh T 2h , then nph=np2h+ne2h, where np2h and ne2h are, respectively, the number of nodes and edges of the coarse mesh T2h . Then, we store node coordinates of T 2h in the np2h first rows of p, that is, in p(1:np2h,1:2). The triangles of the coarse mesh T 2h are stored in the array t2h(1:nt2h,1:3). A fourth array e2h(1:ne2h,1:2) contains mid points of edges of T 2h with the rule node np2h+i belongs to edge [e2h(i,1), e2h(i,2)], for i=1,2,..,ne2h. To summarize, the P1 -iso-P2 /P1 mesh is stored in four arrays p, th, t2h and e2h. Dirichlet boundary nodes are provided by arrays ibc1(1:nbc1) and ibc2(1:nbc2). With the above organization, the pressure vector of nodal values p split as follows 2h p p= . ph In calculations, we only use the coarse mesh part p 2h . The fine mesh part ph is determined from p2h . Matlab supports reading data from files in ASCII format (Matlab function load) and there exists good P1 mesh generators written in Matlab, see e.g. [6]. Matlab function given in A.3 returns a P1 -iso-P2 /P1 mesh from an input P1 mesh. 5 Uzawa conjugate gradient algorithm Let us introduce the functional 1 J(u) = (ut1 A1 u1 + ut2 A2 u2 ) − f1t u1 − f2t u2 2 defined over RNh × RNh , and the subset X = u ∈ RNh × RNh : −B1 u1 − B2 u2 = 0 . Consider the following constrained minimization problem u ∈ X; J(u) ≤ J(v), ∀v ∈ X. (5.1) To (5.1), we associate the Lagrangian function L(u, p) = J(u) − pt (B1 u1 + B2 u2 ) (5.2) defined over RNh ×RNh ×RN2h . A saddle-point (u, p) of L is characterized by the min-max problem L(u, q) ≤ L(v, q) ≤ L(v, p), ∀(v, q) ∈ RNh × RNh × RN2h , (5.3) 5 UZAWA CONJUGATE GRADIENT ALGORITHM 5 or, equivalently, by the saddle-point equations Ai ui − Bit p = fi , i = 1, 2, −B1 u1 − B2 u2 = 0. (5.4) (5.5) The saddle-point equations (5.4)-(5.5) are precisely the algebraic system (3.3). Eq. (5.4) stands for the minimization step of the min-max problem (5.3) while Eq. (5.5) stands for the maximization step. To derive a Lagrange multiplier algorithm, we assume that u = u(p) is the solution of the Poisson equation Ai ui = fi + Bit p, i = 1, 2. (5.6) Then, multiplying (5.6) by ui and substituting the result in (5.2), we get 1 L(u(p), p) = − (ut1 A1 u1 + ut2 A2 u2 ). 2 Introduce the dual functional J ∗ (p) = − min L(u, p) = u 1 t (u A1 u1 + ut2 A2 u2 ), 2 1 where u = u(p) is the solution of (5.6). The saddle-point problem (5.3) now takes the form p ∈ RN2h , J ∗ (p) ≤ J ∗ (q), ∀q ∈ RN2h . (5.7) From (5.6), the mapping p 7→ u(p) is linear and we have u(p + td) = u(p) + tw where w = (w1 , u2 ) is the solution of the uncoupled sensitivity equation Ai wi , = Bit d, i = 1, 2. (5.8) r := ∇J ∗ (p) = B1 u1 + B2 u2 . (5.9) The derivative of J ∗ is then The value of (5.9) computed on the coarse mesh T 2h will be denoted by rp . With the data representation of Section 4, we have 2h r r= rh Then, the gradient rp in the coarse mesh is computed using the formula rpi = r2h i + 1 X h rk , i = 1, 2 . . . 2 (5.10) k∈Vi where Vi is the set of indices of neighbor nodes (in the fine mesh). In our code, (5.10) is computed efficiently using the Matlab function sparse. A practical implementation of the algorithm requires the choice of a preconditioner for computing the derivative (5.9). We use the preconditioner advocated in Cahouet and 5 6 UZAWA CONJUGATE GRADIENT ALGORITHM Chabard [3]. Let Kp and Mp be the Laplacian and mass matrices assembled on the coarse mesh T2h . First an auxiliary unknown z is computed as solution of Kp z = r p (5.11) and then, the gradient g ∈ RN2h is computed via Mp g = αMp z + νrp . (5.12) Remark 1. The preconditioning (5.11)-(5.12) induces the norm |g| 2P = gt rp on RN2h As in [5, 4], a search direction is denoted by −d k (instead of dk ) at each iteration k of the algorithm. If pk+1 = pk − tk dk , then uk+1 = uk − tk wk , where wk is the solution of the sensitivity problem for dk . We also have rk+1 = rk − tkerk , where erk = B1 w1k + B2 w2k . Consequently gk+1 = gk − tk e gk , where e gk is the solution of Kpe zk = erkp Mp e gk = αMpe zk + νerkp . With a search direction −dk , the step size tk is computed as a minimizer of the realvalued function ϕ(t) = J ∗ (pk − tdk ). Since J ∗ is quadratic, it follows that tk = |gk |2P (dk , rk )R = , (dk ,erk )R (dk ,erk )R if −dk is a conjugate gradient direction. With the above preparations, we can now present the preconditioned Uzawa conjugate gradient algorithm for the Stokes problem. Algorithm UCG Iteration 0. Initialization: p0 given Compute u0 = (u01 , u02 ) by solving Ai u0i = fi + Bit p0 , i = 1, 2 r0 = B1 u01 + B2 u02 Compute z0 ∈ RN2h by solving Kp z0 = r0p Compute g0 ∈ RN2h by solving Mp g0 = αMp z0 + νr0p d0 = g 0 Iteration k ≥ 0. Assuming that pk , uk , gk and dk are known Sensitivity: Compute wk ∈ RNh × RNh via 6 7 ASSEMBLY OF MATRICES Ai wik = Bi dk , i = 1, 2. erk = B1 w1k + B2 w2k Compute zk ∈ RN2h via Kpe zk = erkp Compute e gk ∈ RN2h via Mp e gk = νerkp + αe zk Step size: tk = |ghk |2P (dk ,erk ) Update: pk+1 = pk − tk dk , uk+1 = uk − tk wk , Conjugate gradient direction: rk+1 = rk − tkerk , gk+1 = gk − tk e gk . |gk+1 |2P = (gk+1 , rpk+1 )R , βk = |gk+1 |2P |gk |2P dk+1 = gk+1 + βk dk We iterate until |gk |2P = (gk , rkp )R is sufficiently small, typically 6 |gk+1 |P < ε. |g0 |P Assembly of matrices We have to assemble, on the fine mesh T h , stiffness and mass matrices Ki ≡ (∇uih , ∇vih ), Mi ≡ uih , vih ), i = 1, 2 and divergence matrices Bi ∼ (qh , ∂i uih ), i = 1, 2. On the coarse mesh T2h , we have to assemble preconditioning matrices Kp and M p used in (5.11)-(5.12) Kp ∼ (∇gh , ∇qh ), Mp ∼ (gh , qh ). 6.1 Assembly of the Laplacian matrix For a triangle T , let {(xi , yi )}i=1,2,3 be the vertices and {φ}i=1,2,3 the corresponding basis functions. The gradient of φi are given by −1 1 1 1 0 0 y2 − y 3 x3 − x 2 1 y3 − y 1 x1 − x 3 , ∇φt2 = x1 x2 x3 1 0 = 2|T | 0 1 y1 − y 2 x2 − x 1 y1 y2 y3 ∇φt3 ∇φt1 6 8 ASSEMBLY OF MATRICES where |T | is the area of T , i.e. x2 − x 1 x3 − x 1 = (x2 − x1 )(y3 − y1 ) − (x3 − x1 )(y1 − y2 ). 2|T | = det y2 − y 1 y3 − y 1 Let us introduce the following notations xij = xi − xj , and x(T ) yij = yi − yj , x32 = x13 x21 y (T ) i, j = 1, 2, 3, (6.1) y23 = y31 . y12 (6.2) An entry of the element Laplacian matrix K (T ) is given by Z 1 (T ) (T ) (T ) (T ) (T ) Kij = ∇φi ∇φj dx = yi yj + x i xj 4|T | T and we deduce that K (T ) = (T ) (T ) 1 (T ) (T ) t y (y ) + x(T ) (x(T ) )t . 4|T | With Matlab, xi and yi can be computed in a fast way for all triangles using vectorization. Then assembling the Laplacian matrix reduces to two constant loops for computing x(T ) (x(T ) )t and y (T ) (y (T ) )t . By taking into account symmetry properties, the computational cost of the assembling process can be reduced. Matlab vectorized implementation of the assembly of the stiffness matrix is presented in Function 6.1. 6.2 Assembly of the mass matrix An entry of the element mass matrix is given by Z |T | 6 (T ) Mij = φi φj dx = |T | T 12 if i = j, elsewhere, by direct integration. For the global mass matrix, it suffices to compute triangles area. Matlab vectorized implementation of the assembly of the mass matrix is presented in Function 6.2. 6.3 Assembly of the divergence matrix (T ) An entry of the element divergence submatrix B 1 is given by Z |T | (T ) B1ij = ∂1 φi φj dx = ∂1 φi . 3 T (T ) Using notations (6.1) and (6.2), the element divergence sub matrix B 1 (T ) B1 1 = [y (T ) y (T ) y (T ) ] 6 is then 7 9 ASSEMBLY OF RIGHT-HAND SIDES Function 6.1 Assembly of the Laplacian matrix (c x ∂1 u, ∂1 v) + (cy ∂2 u, ∂2 v) function Kh=laplace2d(p,t,cx,cy) %LAPLACE2D Assembly of the Laplacian matrix % Kh=laplace2d(p,t,cx,cy) or Kh=laplace2d(p,t,cx) % p(1:np,1:2) nodes coordinates % t(1:nt,1:3) triangles np=size(p,1); if (nargin==3), cy=cx; end % Triangles area x21=p(t(:,2),1)-p(t(:,1),1); y21=p(t(:,2),2)-p(t(:,1),2); x32=p(t(:,3),1)-p(t(:,2),1); y32=p(t(:,3),2)-p(t(:,2),2); x31=p(t(:,3),1)-p(t(:,1),1); y31=p(t(:,3),2)-p(t(:,1),2); tarea=(x21.*y31-y21.*x31)/2; % Derivatives of shape functions dx=[-y32 y31 -y21]; dy=[ x32 -x31 x21]; ccx=0.25*cx./tarea; ccy=0.25*cy./tarea; % Assembly of sub diagonal elements Kh=sparse(np,np); Kh=Kh+sparse(t(:,2),t(:,1),ccx.*dx(:,2).*dx(:,1)+ccy.*dy(:,2).*dy(:,1),np,np); Kh=Kh+sparse(t(:,3),t(:,1),ccx.*dx(:,3).*dx(:,1)+ccy.*dy(:,3).*dy(:,1),np,np); Kh=Kh+sparse(t(:,3),t(:,2),ccx.*dx(:,3).*dx(:,2)+ccy.*dy(:,3).*dy(:,2),np,np); % Transposition Kh=Kh+Kh.’; % Assembly of diagonal elements for i=1:3 Kh=Kh+sparse(t(:,i),t(:,i),ccx.*dx(:,i).^2+ccy.*dy(:,i).^2,np,np); end (T ) In the same way, the element divergence submatrix B 2 is 1 = [x(T ) x(T ) x(T ) ]. 6 Matlab implementation of the assembly of divergence matrices is given in Function 6.3. (T ) B2 7 Assembly of right-hand sides We only need to assemble the contribution of the external forces, i.e. (f i , vh )Ω , i = 1, 2. Other right-hand sides are computed, during the iterative process, from divergence and mass matrices as detailed in Section 5. Computing the element contribution of external forces is standard (see e.g. [1, 2]). Vectorized Matlab implementation is given in Function 7.1. 8 Implementation of the Uzawa algorithm After incorporating boundary conditions, velocity matrices A 1 and A2 are positive definite. Their Choleski factors R1 and R2 are computed once and for all in the initialization step. 8 IMPLEMENTATION OF THE UZAWA ALGORITHM 10 Function 6.2 Assembly of the mass matrix (cu, v) function Mh=mass2d(p,t,c) %MASSE2D Assembly of the mass matrix % Mh=masse2d(p,t) if c==1, Mh=masse2d(p,t,c) % p(1:np,1:2) node coordinates % t(1:nt,1:3) triangles np=size(p,1); if (nargin==2), c=1; end % Triangles area x21=p(t(:,2),1)-p(t(:,1),1); y21=p(t(:,2),2)-p(t(:,1),2); x31=p(t(:,3),1)-p(t(:,1),1); y31=p(t(:,3),2)-p(t(:,1),2); tarea=(x21.*y31-y21.*x31)/2; % Assembly of sub-diagonal elements cc=c.*tarea/12; Mh=sparse(t(:,2),t(:,1),cc,np,np); Mh=Mh+sparse(t(:,3),t(:,1),cc,np,np)+sparse(t(:,3),t(:,2),cc,np,np); % Transposition Mh=Mh+Mh.’; % Assembly of diagonal element cc=2*cc; Mh=Mh+sparse(t(:,1),t(:,1),cc,np,np)+sparse(t(:,2),t(:,2),cc,np,np)... +sparse(t(:,3),t(:,3),cc,np,np); Function 6.3 Assembly of divergence matrices (q, ∂ 1 u1 ) + (q, ∂2 u2 ) function [B1,B2]=div2d(p,t) %DIV2D Assembly of divergence matrix % [B1,B2]=div2d(p,t) % p(1:np,1:2) node coordinates % t(1:nt,1:3) triangles np=size(p,1); % Derivatives of shape functions x21=p(t(:,2),1)-p(t(:,1),1); y12=p(t(:,1),2)-p(t(:,2),2); x32=p(t(:,3),1)-p(t(:,2),1); y23=p(t(:,2),2)-p(t(:,3),2); x13=p(t(:,1),1)-p(t(:,3),1); y31=p(t(:,3),2)-p(t(:,1),2); dx=[y23 y31 y12]/6; dy=[x32 x13 x21]/6; % Assembly B1=sparse(np,np); B2=sparse(np,np); for i=1:3 for j=1:3 B1=B1+sparse(t(:,i),t(:,j),dx(:,j),np,np); B2=B2+sparse(t(:,i),t(:,j),dy(:,j),np,np); end end The solution to (velocity) linear systems during the iterative process is therefore reduced to backward/forward substitutions. 9 11 NUMERICAL EXPERIMENTS Function 7.1 Assembly of the right-hand side function [fh1,fh2]=stokesrhs(p,t,f1,f2) % STOKESRHS: Assembly of the right-hand side of the Stokes equation % n=size(p,1); % Area of triangles x21=p(t(:,2),1)-p(t(:,1),1); y21=p(t(:,2),2)-p(t(:,1),2); x32=p(t(:,3),1)-p(t(:,2),1); y32=p(t(:,3),2)-p(t(:,2),2); x31=p(t(:,3),1)-p(t(:,1),1); y31=p(t(:,3),2)-p(t(:,1),2); area=(x21.*y31-y21.*x31)/2; % Body forces at triangles center of mass f1h=(f1(t(:,1))+f1(t(:,2))+f1(t(:,3))).*area/9; f2h=(f2(t(:,1))+f2(t(:,2))+f2(t(:,3))).*area/9; % Assembly fh1=full(sparse(t(:,1),1,f1h,n,1)+sparse(t(:,2),1,f1h,n,1)... +sparse(t(:,3),1,f1h,n,1)); fh2=full(sparse(t(:,1),1,f2h,n,1)+sparse(t(:,2),1,f2h,n,1)... +sparse(t(:,3),1,f2h,n,1)); The Laplacian (preconditioner) matrix K p is positive semi-definite. To remove the constant pressure mode, we impose that p = 0 at an arbitrary node, instead of the constraint Z p(x)dx = 0. Ω An additional array ibcp contains the node at which the pressure is prescribed (in the coarse mesh). In the case of a Stokes problem with mixed boundary conditions, the pressure must be prescribed on the Neumann boundary nodes. Then ibcp contains the Neumann boundary nodes (in the coarse mesh). After incorporating boundary conditions, matrices Kp and Mp are positive definite with Choleski factors R Kp and RMp . Note that the nodes numbering, imposed by superimposed meshes, is not suitable for direct linear solvers. Thus, we use the Matlab function symamd (minimum degree ordering) to reduce fill-in. The permutations vectors are s for velocity matrices and ss for pressure matrices. Matlab implementation of Algorithm Uzawa 1 is given in Function 8.1. 9 Numerical experiments In two-dimensional incompressible fluid problems, it is usual to display the stream-lines. If the domain Ω is bounded and simply connected, in order to compute the stream-function ψ, we have to solve the Poisson-Neumann problem −∆ψ = ω, in Ω, (9.1) ∂n ψ = −u · τ, (9.2) where ω = ∂1 u2 − ∂2 u1 is the vorticity and τ the counter-clockwise oriented unit tanget vector at Γ. Problem (9.1)-(9.2) has a unique solution in H 1 (Ω)/R. In the fine mesh Th , 9 12 NUMERICAL EXPERIMENTS Function 8.1 Matlab function for the Uzawa conjugate gradient algorithm function [u1,u2,p,iter]=ucgstokes(R1,R2,RKp,RMp,Mp,B1,B2,e2h,b1,b2,ibc1,ibc2,... ibcp,p,s,ss,alpha,nu,epscg) %UCGSTOKES Uzawa Conjugate gradient algorithm for the Stokes Problem % nh=length(b1); ne2h=size(e2h,1); n2h=nh-ne2h; lnh=[1:size(e2h,1)]+n2h; ie1=e2h(:,1); ie2=e2h(:,2); % Initial velocity u1=zeros(nh,1); u1(s)=R1\(R1’\b1(s)); u2=zeros(nh,1); u2(s)=R2\(R2’\b2(s)); % Initial gradient rh=B1*u1+B2*u2; r2h=rh(1:n2h); r2h=r2h+full(sparse(ie1,1,rh(lnh)/2,n2h,1)+sparse(ie2,1,rh(lnh)/2,n2h,1)); r2h(ibcp)=0; gz=zeros(n2h,1); gz(ss)=RKp\(RKp’\r2h(ss)); bp=alpha*Mp*gz+nu*r2h; bp(ibcp)=0; g=zeros(n2h,1); g(ss)=RMp\(RMp’\bp(ss)); gg=r2h’*g; gg0=gg; % Initial direction d=zeros(nh,1); d(1:n2h)=g; % Uzawa loop tol=1; iter=0; while (tol>epscg & iter<n2h) iter=iter+1; % Sensitivity problems d(lnh)=(d(ie1)+d(ie2))/2; b1=B1’*d; b1(ibc1)=0; w1=zeros(nh,1); w1(s)=R1\(R1’\b1(s)); b2=B2’*d; b2(ibc2)=0; w2=zeros(nh,1); w2(s)=R2\(R2’\b2(s)); % rh=B1*w1+B2*w2; r2hk=rh(1:n2h); r2hk=r2hk+full(sparse(ie1,1,rh(lnh)/2,n2h,1)+sparse(ie2,1,rh(lnh)/2,n2h,1)); r2hk(ibcp)=0; gz=zeros(n2h,1); gz(ss)=RKp\(RKp’\r2hk(ss)); bp=alpha*Mp*gz+nu*r2hk;bp(ibcp)=0; gk=zeros(n2h,1); gk(ss)=RMp\(RMp’\bp(ss)); % Step size tk=gg/(rh’*d); % Update p=p-tk*d; g=g-tk*gk; u1=u1-tk*w1; u2=u2-tk*w2; % New conjugate gradient direction r2h=r2h-tk*r2hk; gg1=r2h’*g; beta=gg1/gg; d(1:n2h)=g+beta*d(1:n2h); % Tolerance tol=min(sqrt(gg1),sqrt(gg1/gg0)); gg=gg1; end the variational formulation of (9.1)-(9.2) is ψh ∈ Hh ; (∇ψh , ∇ϕh ) = (u1h ∂2 ϕh − u2h ∂1 ϕh ), ∀ϕh ∈ Hh , where Hh is given by Hh = ϕh ∈ C 0 (Ω̄), ϕ|T ∈ P1 , ∀T ∈ Th . (9.3) 9 13 NUMERICAL EXPERIMENTS This leads to the algebraic system Kψ = B2t u1 − B1t u2 where K is the Laplacian matrix. As for the pressure equations, we impose ψ = 0 at an arbitrary node to ensure the uniqueness. In all numerical experiments, Dirichlet boundary conditions are taken into account by penalization. 9.1 Test case with exact solution We consider the domain Ω = (0, 1) × (0, 1) and we take α = 0 and ν = 1 in 2.1. The right-hand side in (2.1) is adjusted such that the exact solution is u1 (x, y) = − cos(2πx) sin(2πy) + sin(2πy), u 2 (x, y) = sin(2πx) cos(2πy) − sin(2πx), p(x, y) = 2π(cos(2πy) − cos(2πx)), with the boundary condition u = 0 on Γ. The domain Ω is first discretized by a uniform mesh of size h = 1/16 (289 nodes and 512 triangles in the fine mesh). This initial mesh is successively refined to produce meshes with sizes 1/32, 1/64, 1/128 and 1/256 (respectively 1089, 4225, 16641 and 66049 nodes). The number of iterations, L 2 and H 1 errors for u and p are summarized in Table 1. Figures 2-3 show the velocity field and isobar lines of the flow. Mesh size Iteration ||u − uh ||L2 ||u − uh||H 1 ||p − ph ||L2 1 16 9 4.9936 × 10−2 3.8961 × 10−1 3.2636 × 10−1 1 32 9 1.2817 × 10−2 1.0218 × 10−1 8.6462 × 10−2 1 64 8 3.2238 × 10−3 2.7591 × 10−2 2.3699 × 10−2 1 128 8 8.0688 × 10−4 7.5234 × 10−3 6.8586 × 10−3 1 256 8 2.0174 × 10−4 2.1973 × 10−3 2.1075 × 10−3 Table 1: Performances of the Uzawa conjugate gradient algorithm 9.2 Flow around a cylinder This test problem is derived from a benchmark problem described in [7]. The geometry and boundary conditions are shown in Figure 4. The kinematic viscosity is ν = 10 −3 and the inflow condition is u1 (0, y) = 0.3 × 4y(0.4 − y)/(0.4)2 . The parameter α in (2.1) is set to 1. The center of the cylinder is (0.25, 0.2) and the diameter is 0.1. This gives a Reynolds number of Re = 30 based on the diameter of the cylinder and the maximum of the inflow velocity. 9 14 NUMERICAL EXPERIMENTS 1 0 0 1 Figure 2: Velocity field Figure 3: Isobar lines u =parabola, u =0 1 u=0 2 p=0 0.4 0 0 0.25 0.5 0.75 1 1.25 1.5 1.75 Figure 4: Geometry and boundary conditions of the flow around cylinder problem. 2 A 15 APPENDIX The domain is discretized by a non uniform mesh consisting of 6888 nodes and 13440 triangles. Convergence is reached after 17 iterations. Isobar lines and stream lines are shown in Figures 5-6. Tables 2-4 show the good convergence properties of the preconditioning (5.11)-(5.12) when α/ν 1. Figure 5: Isobar lines for the flow around cylinder problem, Re = 30 Figure 6: Stream lines for the flow around cylinder problem, Re = 30 α/ν 103 104 105 106 Iterations 7 6 7 7 Table 2: Number of iterations vs. parameters ratio, for Re = 30 A A.1 Appendix Main program for test case with exact solution %%---------- Test case with exact solution % constants alpha=0; nu=1; Pen=10^10; % Penalty for Dirichlet boundary conditions epscg=10^-6; % Tolerance for Uzawa algorithm % mesh load carre289 p th t2h e2h ibc1 ibc2 ibcp nph=size(p,1); np2h=nph-size(e2h,1); nth=size(th,1); fprintf(’Mesh : nph=%4d nth=%4d \n’,nph,nth) A 16 APPENDIX α/ν 104 105 106 107 Iterations 5 6 6 7 Table 3: Number of iterations vs. parameters ratio, for Re = 300 α/ν 105 106 107 108 Iterations 5 5 6 7 Table 4: Number of iterations vs. parameters ratio for Re = 3000 % % Matrices generation / velocity K=laplace2d(p,th,nu); [B1,B2]=div2d(p,th); A1=K; A2=K; s=symamd(A1); % % Matrices generation / pressure Kp=laplace2d(p(1:np2h,:),t2h,1); Mp=mass2d(p(1:np2h,:),t2h); MMp=Mp; ss=symamd(Kp); % % Right hand side/ exact solution x=p(:,1); y=p(:,2); pi2=2*pi; pre=pi2*(cos(pi2*y)-cos(pi2*x)); u1e=-cos(pi2*x).*sin(pi2*y)+sin(pi2*y); u2e= sin(pi2*x).*cos(pi2*y)-sin(pi2*x); f1=-pi2*pi2*sin(pi2*y).*(2*cos(pi2*x)-1)+pi2*pi2*sin(pi2*x); f2= pi2*pi2*sin(pi2*x).*(2*cos(pi2*y)-1)-pi2*pi2*sin(pi2*y); [b1,b2]=stokesrhs(p,th,f1,f2); % Boundary conditions (Penalization) A1(ibc1,ibc1)=A1(ibc1,ibc1)+Pen*speye(length(ibc1)); A2(ibc2,ibc2)=A2(ibc2,ibc2)+Pen*speye(length(ibc2)); Kp(ibcp,ibcp)=Kp(ibcp,ibcp)+Pen*speye(length(ibcp)); MMp(ibcp,ibcp)=MMp(ibcp,ibcp)+Pen*speye(length(ibcp)); b1(ibc1)=0; b2(ibc2)=0; % Choleski factorization R1=chol(A1(s,s)); R2=chol(A2(s,s)); RKp=chol(Kp(ss,ss)); RMp=chol(MMp(ss,ss)); clear A1 A2 Kp MMp % Uzawa/CG pr=zeros(nph,1); [u1,u2,pr,iter]=ucgstokes(R1,R2,RKp,RMp,Mp,B1,B2,e2h,b1,b2,ibc1,ibc2,ibcp,... pr,s,ss,alpha,nu,epscg); % L^2 and H^1 errors M=masse2d(p,th,1); du1=u1-u1e; du2=u2-u2e; dp=pr-pre; errL2u=du1’*M*du1+du2’*M*du2; errL2p=sqrt(dp’*M*dp); errH1u=errL2u+du1’*K*du1+du2’*K*du2; fprintf(’iter=%4d Err:u/L2 %15.8e /H1 %15.8e Err:p/L2 %15.8e \n’,iter,... sqrt(errL2u),sqrt(errH1u),errL2p) A APPENDIX A.2 Main program for flow around cylinder %%---------Flow around cylinder % constant alpha=0; nu=10^-3; Pen=10^15; epscg=10^-6; % mesh load cylinder6888 p th t2h e2h ibc1e ibc1i ibc2 ibcp ibc1=union(ibc1e,ibc1i); nph=size(p,1); np2h=nph-size(e2h,1); fprintf(’Mesh : nph=%4d nth=%4d \n’,nph,size(th,1)) % Matrices generation / velocity K=laplace2d(p,th,nu); M=mass2d(p,th,alpha); [B1,B2]=div2d(p,th); A1=M+K; A2=M+K; s=symamd(A1); % Matrices generation / pressure Kp=laplace2d(p(1:np2h,:),t2h,1); Mp=mass2d(p(1:np2h,:),t2h); MMp=Mp; ss=symamd(Kp); % Right hand side b1=zeros(nph,1); b2=zeros(nph,1); % Boundary conditions A1(ibc2,ibc2)=A1(ibc2,ibc2)+Pen*speye(length(ibc2)); A2(ibc2,ibc2)=A2(ibc2,ibc2)+Pen*speye(length(ibc2)); Kp(ibcp,ibcp)=Kp(ibcp,ibcp)+Pen*speye(length(ibcp)); MMp(ibcp,ibcp)=MMp(ibcp,ibcp)+Pen*speye(length(ibcp)); u1bc=0.3*0.4*p(ibc1e,2).*(0.4-p(ibc1e,2))/(0.4^2); b1(ibc1e)=Pen*u1bc; % % Choleski factorization R1=chol(A1(s,s)); R2=chol(A2(s,s)); RKp=chol(Kp(ss,ss)); RMp=chol(MMp(ss,ss)); clear A1 A2 Kp MMp % % Uzawa/CG pr=zeros(nph,1); [u1,u2,pr,iter]=ucgstokes(R1,R2,RKp,RMp,Mp,B1,B2,e2h,b1,b2,ibc1,ibc2,ibcp,... pr,s,ss,alpha,nu,epscg); % % Stream-function ibcsl(1)=1; K(ibcsl,ibcsl)=K(ibcsl,ibcsl)+Pen*speye(length(ibcsl)); b=B2’*u1-B1’*u2; b(ibcsl)=0; sf=K\b; A.3 P1 -iso-P2 /P1 mesh generator from P1 mesh function [ph,th,e2h,refh]=meshp1isop2(p2h,t2h,ref2h) %MESHP1ISOP2 Generates P1-iso-P2 mesh from P1 mesh % np2h=size(p2h,1); nt2h=size(t2h,1); % Mesh edges e2h=[t2h(:,[1,2]);t2h(:,[1,3]);t2h(:,[2,3])]; e2h=unique(sort(e2h,2),’rows’); 17 REFERENCES 18 % New vertices ph=[p2h;(p2h(e2h(:,1),:)+p2h(e2h(:,2),:))/2]; % Edge mid points ne=size(e2h,1); lnv=[(np2h+1):(np2h+ne)]; A=sparse(e2h(:,1),e2h(:,2),lnv,np2h,np2h); A=A+A.’; mp1=zeros(nt2h,1); mp2=mp1; mp3=mp1; for i=1:nt2h mp1(i)=A(t2h(i,1),t2h(i,2)); mp2(i)=A(t2h(i,2),t2h(i,3)); mp3(i)=A(t2h(i,3),t2h(i,1)); end % New triangles th=zeros(4*nt2h,3); th(1:nt2h,:)=[t2h(:,1) mp1 mp3]; th((nt2h+1):2*nt2h,:)=[mp1 t2h(:,2) mp2]; th((2*nt2h+1):3*nt2h,:)=[mp2 t2h(:,3) mp3]; th((3*nt2h+1):4*nt2h,:)=[mp1 mp2 mp3]; if (nargin==2) return end % Boundary nodes ltc=find(ref2h(t2h(:,1))==1 & ref2h(t2h(:,2))==1 & ref2h(t2h(:,3))==1); ntc=length(ltc); if (ntc==0) ibc=find(ref2h(e2h(:,1))==1 & ref2h(e2h(:,2))==1); refe=zeros(ne,1); refe(ibc)=1; refh=[ref2h;refe]; else % Corner triangle without internal node ref=ref2h; d2h=full(sparse(e2h(:,1),1,1,np2h,1)+sparse(e2h(:,2),1,1,np2h,1)); for i=1:ntc i1=t2h(ltc(i),1); i2=t2h(ltc(i),2); i3=t2h(ltc(i),3); if (d2h(i1)==2) ref([i2;i3])=2; elseif (d2h(i2)==2) ref([i3;i1])=2; else ref([i1;i2])=2; end end ib1=find(ref(e2h(:,1))>=1 & ref(e2h(:,2))>=1); ib2=find(ref(e2h(:,1))==2 & ref(e2h(:,2))==2); ibc=setdiff(ib1,ib2); refe=zeros(ne,1); refe(ibc)=1; refh=[ref2h;refe]; end References [1] Alberty J., Carstensen C. and Funken S.A. Remarks around 50 lines of matlab: short finite element implementation. Numer. Algorithms, 20:117–137, 1999. REFERENCES 19 [2] Alberty J., Carstensen C., Funken S.A. and Klose R. Matlab implementation of the finite element method in elasticity. Computing, 69:239–263, 2002. [3] Cahouet J. and Chabard J. P. . Some fast 3-D solvers for the generalized Stokes problem. Internat. J. Numer. Methods Fluids, 8:269–295, 1988. [4] Glowinski R. Numerical methods for fluids (part 3). In Ciarlet P.G. and Lions J.L., editors, Numerical Methods for Fluids (Part 3), volume IX of Handbook of Numerical Analysis, pages 3–1074. North-Holland, Amsterdam, 2003. [5] Glowinski R. and Le Tallec P. Augmented Lagrangian and Operator-splitting Methods in Nonlinear Mechanics. Studies in Applied Mathematics. SIAM, Philadelphia, 1989. [6] Persson P.-O. and Strang G. A simple mesh generator in Matlab. SIAM Rev., 42:329–345, 2004. [7] Schäfer M. and Turek S. Benchmark computations of laminar flow around a cylinder. Notes Numer. Fluid Mech., 52:547–566, 1996.
© Copyright 2026 Paperzz