<!DOCTYPE html> 4 Two Dimensional Potential Flows‣ Notes on the Finite Element Method
Notes on the Finite Element Method

Chapter 4 Two Dimensional Potential Flows

4.1 Equations and Boundary Conditions

4.1.1 Potential and Stream functions.

Begin with the mass conservation equation:

𝐮=0 (4.1)

Because the curl of the gradient of any scalar function has to be zero, if the vorticity vector 𝝎 defined as

𝝎=×𝐮=0 (4.2)

the velocity can be defined as the gradient of a scalar potential function:

𝐮=ϕ (4.3)

then the governing equation for ϕ comes directly from continuity:

ϕ=2ϕ=0 (4.4)

This is the simplest possible elliptic pde: Laplace’s equation. Since there can be no flow through a boundary, the required boundary conditions are that the normal component of ϕ vanish at the boundary. These are neumann conditions.

For a two dimensional flow (can be extended to axisymmetric) flow, a streamfunction can be defined as:

u=-ψy;v=ψx (4.5)

In general, the streamfunction is related to the vorticity by:

2ψ=-𝝎 (4.6)

The condition that the vorticity be zero then gives:

2ψ=0 (4.7)

so that both the stream and potential functions satisfy Laplace’s equation. This is very surprising. Usually the combined NS and mass conservation equations have to be solved for the velocities and pressure. Now a single (very simple) equation has to be solved for a single dependent variable: the potential function, or the streamfunction.. Part of the mystery is wrapped up in the condition that the vorticity has to be zero. For completeness, consider how to evaluate the pressure field given the potential ϕ..

4.1.2 The Bernouilli Equation

Once the streamfunction or the potential function is know, the velocities are given by either equation 4.3, or equation 4.5. The pressure is then given by Bernouilli’s equation. The momentum equation (now called the Euler equation) can be written as:

𝐮t+(𝐮)𝐮=-pρ+𝐠 (4.8)

Noting that

(𝐮)𝐮=12(u2)-𝐮××𝐮 (4.9)

and with 𝝎=×𝐮=0, for a constant density fluid, the momentum equation is

𝐮t+12(u2)-𝐮×𝝎=-1ρ(p+ρgz) (4.10)

This is Bernouilli’s equation. The component parallel to a streamline (or to 𝐮) is:

ut+s(12u2+pρ+gz)=0 (4.11)

where s represents distance along a streamline. This is because 𝝎 is perpendicular to 𝐮. The component normal to the streamline is:

uvs=-1ρ(p+ρgz)n (4.12)

which shows that for a flow to change direction, the pressure must vary in the direction normal to the streamline.

For steady flow, the inviscid momentum equation can be integrated between any points on a streamline with the result that

12u2+pρ+gz=B(ψ) (4.13)

in words, the expression on the left hand side is a constant along the streamline. This is Bernouilli’s equation for steady, inviscid, rotational flow. The finite element method is ideally suited for such problems in two dimensions, particularly when the domain is irregular.

4.2 Grids

4.2.1 DistMesh

Read Strang pp 305-316
Mesh regularity is a desirable property for Finite Elements. By regularity we don’t mean size, what we are looking for are grids where there are no long, skinny triangles. Ideally the grid would consist only of equlqteral triangles. Persson wrote DistMesh with this goal in mind. Three grids produced by DistMesh are illustrated in figure 4.1.

Different grids produced by DistMesh. Left: simple
rectangular gria; center: circle in a rectangle; right: same with
progressively varying mesh size.

Figure 4.1: Different grids produced by DistMesh. Left: simple rectangular gria; center: circle in a rectangle; right: same with progressively varying mesh size.

Each mesh consists of M nodes. The gridding procedure determines coordinates for each node as well as a connection table consisting of a list of the three nodes at the vertex of each element.

The script to produce these plots is listed in 4.5.1

4.2.2 Trial Functions and Elements

Just as in the one-dimensional case, the test function is defined as having unit value at one particular node, and zero at all other nodes. A test function is illustrated in figure 4.2.

A single linear test function. The value is non-zero at a
single node of the grid. Each of the slanting sides is one
element. If the elements were all equilateral, they would always
be six elements contributing to each TF.

Figure 4.2: A single linear test function. The value is non-zero at a single node of the grid. Each of the slanting sides is one element. If the elements were all equilateral, they would always be six elements contributing to each TF.

It is teepee shaped, the central node is directly connected to six peripheral nodes: the functions has six sides, or elements.

Test and Trial Functions

As in the one-dimensional case, there are several choices for the polynomial representing the test (or trial) function in an element. The FEM procedure (Galerkin’s method) consists of representing the dependent variable (e.g. u(x,y)) as an expansion over a set of test functions ϕm(x,y), in such a way that the governing equation and BC provide estimates of the solution at each node. The test functions are always chosen to be polynomials:

u(x,y)=m=1Mumϕm(x,y)whereϕm=k=1KCk,mxp(k)yq(k) (4.14)

The constant um is the value of the solution at node m.

Linear Test Functions

The simplest representation uses linear polynomials. The most general form for a two dimensional test function is ϕm(x,y)=C1,m+C2,mx+C3,my. This conforms to equation 4.14 with k, p and q related as in table 4.1.

k 1 2 3
p(k) 0 1 0
q(k) 0 0 1
Table 4.1: Powers p,q as a function of k for Linear TF.

Each triangular element requires three TF, corresponding to the maximum value occuring at each of the three vertices.

The general approach to finding the coefficients in equation 4.14 is to write a system of equations that satisfies the constraint that each TF is unity at a vertex and zero at the three other vertices. A reference element, known as the canonical triangle, with coordinates 0,0; 1,0; and 0,1 is illustrated in the left frame of figure 4.3.

Elements of a test function. Left: the canonical triangle.
The bold set numbers identify the locations where each trial
function is 1. Right: an arbitrary triangle (In Cowper’s
notation).

Figure 4.3: Elements of a test function. Left: the canonical triangle. The bold set numbers identify the locations where each trial function is 1. Right: an arbitrary triangle (In Cowper’s notation).

For this example, the three equations for ϕ1 are:

C11 = 1,ϕ1@(0,0) (4.15)
C11+C21 = 0,ϕ1@(0,1)
C11+C31 = 0,ϕ1@(1,0)

The solution is: C11=1, C21=-1 and C31=-1

This approach may be extended to all three test functions in one step by writing:

𝒯𝒞=or, explicitly:[100110101][C11C12C13C21C22C23C31C32C33]=[100010001] (4.16)

𝒯 is made up of the values 1,x,y at each of the three nodes. Then 𝒞=𝒯-1 is the matrix of coefficients. In this case

𝒞=[C11C12C13C21C22C23C31C32C33]=[100-110-101] (4.17)

For the canonical triangle, the three test functions are therefore:

ϕ1=1-X-Y,ϕ2=X,ϕ3=Y. (4.18)

These 3 functions are illustrated in figure 4.4.

The three linear test functions in the canonical triangle.

Figure 4.4: The three linear test functions in the canonical triangle.

Other choices of test functions include quadratic and cubic Legendre polynomials and quintic Hermite polynomials.

For the general triangle illustrated on the right of figure 4.3. The coordinates of each vertex are given in table 4.2.

Vertex x y
j 0.1 0.1
k 1 0.25
l 0.25 1
Table 4.2: Vertex coordinates for the general triangle illustrated on the right of figure 4.3.

The matrices 𝒯 and 𝒞 are:

𝒯=[1-b01a010c];𝒞=1bc+ac[acbc0-cc0-a-ba+b] (4.19)

4.3 The Stream Function

If the velocity is solenoidal (meaning the velocity satisifies ×𝒖=𝝎=0), the velocity can be written as the gradient of a potential function φ(x,y)11 1 please do not confuse the potential function φ with the test functions ϕ. For two dimensional flow, a streamfunction ψ(x,y) may also be defined. The streamfunction is related to the velocities through:

u=ψy,v=-ψx. (4.20)

Both potential and streamfunctions satisfy Laplace’s equation, but with boundary conditions expressed differently in each case. For uniform streaming flow, the boundary conditions specify a non-zero velocity at two ends of the domain, and zero velocity along two bounding walls. If the streamwise velocity is constant, equal to one, the problem for the streamfunction is:

2ψ=0ψ(-1,y)=ψ(1,y)=y,ψ(x,-1)=-1,ψ(x,1)=1. (4.21)

Note that both potential and streamfunctions need only be defined to within an arbitrary constant.

4.3.1 Weak Form

To get the weak form multiply equation 4.21 by a test functions ϕm(x,y) and integrate over the whole domain:

A(2ψx2+2φy2)ϕm𝑑a=0 (4.22)

Integrate by parts and use the divergence theorem to get:

Sφnϕm𝑑s-A(φxϕmx+φyϕmx)𝑑a=0. (4.23)

Because the boundary conditions are Dirichlet and the solution along the boundaries is known a priory, the term on the left of equation 4.23. The solution ψ is expanded in terms of test/trial functions, take to be linear polynomials:

φ(x,y)=n=1Nψnϕn(x,y) (4.24)

where the ψm represent the solution at each node. Introducing this expansion into equation 4.23 gives

n=1NA(ϕmxϕnx+ϕmyϕnx)𝑑aφn=Sφnϕm1d𝑑s (4.25)

The right hand side of equation 4.25 represents forcing along the boundaries by nonhomogeneous Neumann boundary conditions. To remain consistent with the Divergence theorem, the integral must be evaluated in the clockwise direction around the domain. The polynomial order of the testfunctions used along the edges, ϕm1d, must be consistent with the order of the interior TF: if linear TF are used in the interior then one-dimensional linear TF are used to evaluate the forcing along the boundary.

Because the boundary conditions for the streamfunction problem are Dirichlet, the right hand side of equation 4.25 is zero. Then then matrix form of equation 4.25is

𝒦𝝍=0whereKmn=A(ϕmxϕnx+ϕmyϕnx)𝑑a (4.26)

This is a system of M equations, but there are only M-D variables, where D is the number of Dirichlet nodes. Denote the known part of the streamfunction values as 𝝍^, and the interior values as 𝝍~. If the order of the sequence of M nodes is arranged such that all the boundary nodes come before the interior nodes, schematically equation 4.26 looks like:

𝒦𝝍=[12DD+1D+2M12DD+1D+2𝒦^𝒦~M][𝝍^𝝍~]=0 (4.27)

The elements of 𝒦 above the double horizontal line are of no use, since the solution at the correponding (boundary) nodes is known. The matrix 4.25 multiplies a know quantity. Keeping the known and unknown parts of equation 4.27 on the right and left side gives:

𝒦~𝝍~=-𝒦^𝝍^ (4.28)

4.3.2 Assembly

Consider the 3×3 grid illustrated in figure 4.5.

A simple

Figure 4.5: A simple 3×3 grid. Nodes are numbered with a bold font and element numbers are show in large characters.

There are M=9 nodes, of which D=8 are at the boundaries We shall need the stiffness matrix 𝒦. Following

Element Matrices

The one-dimensional stiffness matrix is defined in equation 1.23. In two dimensions we use Maxima to find the elements of 𝒦e are:

Kemn=A(ϕmxϕnx+ϕmyϕnx)𝑑a=A[2-1-1-110-101] (4.29)

where A is the area of the test function.

Global Matrices

The assembly of 𝒦 after the contributions from elements 1 and 2 is as follows:

𝒦=A[2-10-100000-110000000000000000-100100000000000000000000000000000000000000000000000000];A[2-10-100000-12000000-1000000000-10020000-10000000000000000000000000000000000000-10-100002]. (4.30)

It is useful to notice that after contribution from the second element have been added in, the bottom line of 𝒦 is no longer zero. This is because element 2 includes element 9 as one ot the vertices, corresponding to the last row of 𝒦. After adding in the six other elements, 𝒦 becomes:

𝒦=12[2-10-100000-14-100000-20-120-10000-10040-100-200-10400-1-2000-102-10000000-14-1-20000-10-1200-20-2-20-208]. (4.31)

The top 8 rows of 𝒦 are to be ignored. The last row shows that the value at the unknown node 9 is equal to the average of the values at nodes 2, 4, 5 and 7. This is the classic five-point Laplacian. The solution is ψ9=ψ4=ψ6=0.

To evaluate the streamlines for fluid flowing over a cylinder, we use grid illustrated in the center of figure LABEL:Fi:C4S3figure1. We need to specify the streamfunction on all boundaries, including the cylinder, where we take the streamfunction to be zero. The solution, obtained with script LABEL:sec:OctaveC4S4figure6 is illustrated in figure 4.6.

Streamlines obtained with
script 

Figure 4.6: Streamlines obtained with script 4.5.2 for flow around a circle of diameter 1. The contour line interval is 1/2. The grid includes 11572 nodes.

4.4 The Potential Function

The potential function φ still solves Laplace’s equation but the boundary conditions are Neumann conditions on the normal gradient at a boundary:

2φ=0;φn=0on all boundaries exceptφx=1onx=±xmax. (4.32)

4.4.1 Weak Form

The weak form is still given by equation 4.25, however the right hand side of that equations can no longer be neglected along all the boundaries. At solid boundaries (top and bottom of channel and cylinder), the normal gradient is zero, so there is no contribution. Along the right and left boundaries, the right hand term must be taken into account.

The matrix form for the potential flow problem is

𝒦𝝋=𝑭where𝑭=Sϕm𝑑s (4.33)

Contribution to the boundary forcing 𝑭 are due to the nonhomogeneous Neumann boundary conditions along the right and left boundaries. Because linear TF are used in the interior, the test functions ϕm1d along the edge are straight lines, and their average height is always 1/2. Along the edge, these TFs are the same as illustrated in figure  1.4. The base of the test function for the first and last nodes is half that of the other boundary TF. The boundary contributions are therefore:

𝑭x=1=[x(E(2),2)-x(E(1),2)x(E(3),2)-x(E(1),2)x(E(nE),2)-x(E(nE-2),2)x(E(nE),2)-x(E(nE-1),2)] (4.34)

where x(E,2) are the ordinates of all nodes along the right (East, x=1) boundary. The boundary forcing term for the left side of the grid is minus the right side boundary forcing, since φ/n=-1 along the left boundary.

Attempts to solve the system 4.33 run into the further difficulty that there is no information about the mean value of φ. Because of this the matrix 𝒦 is singular. The way around this is to augment the system 4.32 by adding a constraint that the mean value of ϕ is some known value, equal to zero. This leads to an augmented matrix system:

[K1,1K1,2K1,M-1K1,M1K2,1K2,2K2,M-1K2,M1KM-1,1KM-1,2KM-1,M-1KM-1,M1KM,1KM,2KM,M-1KM,M111110][φ1φ2φM-1φMλ]=[F1F2FM-1FM0] (4.35)

The potemtial function derived by solving the linear system 4.35 is illustrated in figure 4.7. The grid is the same as the used to produce figure LABEL:Fi:C4S4figure6.

Potential function

Figure 4.7: Potential function φ. lines of constant potential are normal an any location to the strealines illustrated in figure LABEL:Fi:C4S4figure6. The contour line interval is 1/2. The grid includes 11572 nodes.

Exercises

  1. 1.

    Reproduce figure 4.6 for an ellipse at some non-zero angle of attack, and the NACA airfoil described in Persson’s website.

4.5 Scripts

4.5.1 Octave: Three DistMesh Grids

clear;
%%ID Chap 4 Sec 2 3 grids drawn with distmesh
%% Laplaces equation in FEM is -K*soln=Force
%% requires distmesh be installed in path
%% requires ShowMesh.m
hmin=0.1;% very few values work. was hmin=1
xmin=-1.5;xmax=1.5;ymin=-1;ymax=1;
pfix=[xmin,ymin;xmin,ymax;xmax,ymin;xmax,ymax];% fixed node positions
bbox=[xmin,ymin;xmax,ymax];%% LL and UR corners of bounding box
%% function that returns distance from point p to rectangle xmin,xmax,ymin,ymax
fd=inline(”drectangle(p,xmin,xmax,ymin,ymax)”,”p”);
[xp,tp]=distmesh2d(fd,@huniform,hmin,bbox,pfix);
np=length(xp(:,1));ne=length(tp(:,1));
set(gcf,’position’,[10,1000,1500,400]);clf;
axes(’position’,[0.03,0.075,0.3,0.8]);
ShowMesh(xp,tp);title(’RectangularGrid’,’fontsize’,14);
radius=0.25;
fd=inline(”ddiff(drectangle(p,xmin,xmax,ymin,ymax),dcircle(p,0,0,radius))”,”p”);
[xp,tp]=distmesh2d(fd,@huniform,hmin,bbox,pfix);
axes(’position’,[0.36,0.075,0.3,0.8]);
ShowMesh(xp,tp);title(’CircleInsideRectangularGrid’,’fontsize’,14);
maxh=4;
fh=inline(”min(2*sqrt(sum(p.^2,2))/radius-1,maxh)”,”p”);%
hmininit=0.025;
[xp,tp]=distmesh2d(fd,fh,hmininit,bbox,pfix);
axes(’position’,[0.69,0.075,0.3,0.8]);
ShowMesh(xp,tp);title(’RefinedGridNearCylinder’,’fontsize’,14);
set(gcf,’paperpositionmode’,’manual’,’paperposition’,[0.250.25154])
print-dpng../../words/figs/C4/C4S2figure1.png

4.5.2 Octave: Stream Function

clear;
%%ID Chap 4 Sec 3 del^2 psi=0, flow around cylinder;
%%ID Dirichlet BC on all boundaries
%% Make a Grid
hmin=0.1;
xmin=-5;xmax=5;ymin=-5;ymax=5;
pfix=[xmin,ymin;xmin,ymax;xmax,ymin;xmax,ymax];% fixed node positions
bbox=[xmin,ymin;xmax,ymax];%% LL and UR corners of bounding box
radius=0.5;
fd=inline(”ddiff(drectangle(p,xmin,xmax,ymin,ymax),dcircle(p,0,0,radius))”,”p”);
[xp,tp]=distmesh2d(fd,@huniform,hmin,bbox,pfix);
np=length(xp(:,1));nelement=length(tp(:,1));
%%locateboundaries
smallno=1e-8;%anysmallermakestrouble
N=find(xp(:,2)>ymax-smallno);[~,order]=sort(xp(N,1));N=N(order);
S=find(xp(:,2)<ymin+smallno);[~,order]=sort(xp(S,1));S=S(order);
W=find(xp(:,1)<smallno+xmin);[~,order]=sort(xp(W,2));W=W(order);nW=length(W);
E=find(xp(:,1)>xmax-smallno);[~,order]=sort(xp(E,2));E=E(order);nE=length(E);
bndedges=boundedges(xp,tp);bndnodes=[bndedges(:,1);bndedges(end,2)];%allbnd
bndnodes=[bndedges(:,1);bndedges(end,2)];
%%AssembleGlobalmatrixKelementbyelement
%%LinearTF
K=sparse(np,np);%%initialize
forke=1:nelement
␣␣nodes=tp(ke,:);
␣␣T=[ones(3,1),xp(nodes,:)];
␣␣Area=abs(det(T))/2;
␣␣C=inv(T);
␣␣grad=C(2:3,:);
␣␣Ke=Area*transpose(grad)*grad;%stiffnesscontribution
␣␣K(nodes,nodes)=K(nodes,nodes)+Ke;
end
%%setDirichletBC
outnodes=unique([N;W;S;E]);psi=zeros(np,1);psi(outnodes)=xp(outnodes,2);
cylnodes=setdiff(bndnodes,outnodes);psi(cylnodes)=0;
Dirichlet=[outnodes;cylnodes];
Interior=setdiff([1:np]’,Dirichlet);
tildeK=K(Interior,Interior);
hatK=K(Interior,Dirichlet);
psi(Interior)=tildeK\(-hatK*psi(Dirichlet));
%%Plot
set(gcf,’position’,[10,1000,1200,1200]);clf;
minpsi=-5;maxpsi=5;incpsi=0.5;
tricontour(tp,xp(:,1),xp(:,2),psi,[minpsi:incpsi:maxpsi],’k’);holdon
%tricontour(tp,xp(:,1),xp(:,2),psi,[00],’k’);
%%showcylinder
theta=linspace(0,2*pi,37);
plot(cos(theta)/2,sin(theta)/2,’k’,’linewidth’,2);%radiusis1/2
xlabel(’x’,’fontsize’,16,’fontweight’,’bold’);
ylabel(’y’,’fontsize’,16,’fontweight’,’bold’);
axis([-5,5,-5,5])
set(gcf,’paperpositionmode’,’manual’,’paperposition’,[0.250.251212])
print-dpng../../words/figs/C4/C4S3figure6.png

4.5.3 Octave: Potential Function

%%ID Chap 4 Sec 3 del^2 varphi=0, flow around cylinder;
%%ID Neumann BC on all bnd, with constraint
%% Make a Grid
hmin=0.1;
xmin=-5;xmax=5;ymin=-5;ymax=5;
pfix=[xmin,ymin;xmin,ymax;xmax,ymin;xmax,ymax];% fixed node positions
bbox=[xmin,ymin;xmax,ymax];%% LL and UR corners of bounding box
radius=0.5;
fd=inline(”ddiff(drectangle(p,xmin,xmax,ymin,ymax),dcircle(p,0,0,radius))”,”p”);
[xp,tp]=distmesh2d(fd,@huniform,hmin,bbox,pfix);
np=length(xp(:,1));nelement=length(tp(:,1));
%%locateboundaries
smallno=1e-8;%anysmallermakestrouble
N=find(xp(:,2)>ymax-smallno);[~,order]=sort(xp(N,1));N=N(order);
S=find(xp(:,2)<ymin+smallno);[~,order]=sort(xp(S,1));S=S(order);
W=find(xp(:,1)<smallno+xmin);[~,order]=sort(xp(W,2));W=W(order);nW=length(W);
E=find(xp(:,1)>xmax-smallno);[~,order]=sort(xp(E,2));E=E(order);nE=length(E);
%%AssembleGlobalmatrixKelementbyelement
%%LinearTF
K=sparse(np,np);
forke=1:nelement
␣␣nodes=tp(ke,:);
␣␣T=[ones(3,1),xp(nodes,:)];
␣␣Area=abs(det(T))/2;
␣␣C=inv(T);
␣␣grad=C(2:3,:);
␣␣Ke=Area*transpose(grad)*grad;
␣␣K(nodes,nodes)=K(nodes,nodes)+Ke;
end
%%augmentK
K=[K,ones(np,1);ones(1,np),0];
Force=zeros(np,1);
%%minussignonwestsidebecauseintegrationpathinreverse
Force(W(1))=-(xp(W(2),2)-xp(W(1),2));%deltayfor1stnodeonL
Force(W(nW))=-(xp(W(nW),2)-xp(W(nW-1),2));%deltay
Force(W(2:nW-1))=-(xp(W(3:nW),2)-xp(W(1:nW-2),2));%deltaybtwnends
Force(E(1))=xp(E(2),2)-xp(E(1),2);%deltayfor1stnodeonR
Force(E(nE))=xp(E(nE),2)-xp(E(nE-1),2);%
Force(E(2:nE-1))=xp(E(3:nE),2)-xp(E(1:nE-2),2);%
Force=Force/2;%becausetheaverageheightofeachtriangularelementis1/2
Force=[Force;0];
varphi=K\Force;varphi(np+1)
set(gcf,’position’,[10,1000,1200,1200]);clf;
minvarphi=min(varphi);maxvarphi=max(varphi);rngvarphi=maxvarphi-minvarphi;nclines=11;
tricontour(tp,xp(:,1),xp(:,2),varphi,[-5:0.5:5],’k’);holdon
tricontour(tp,xp(:,1),xp(:,2),varphi,[00],’k’);
theta=linspace(0,2*pi,37);plot(cos(theta)/2,sin(theta)/2,’k’,’linewidth’,2);%cylinder
xlabel(’x’,’fontsize’,16,’fontweight’,’bold’);
ylabel(’y’,’fontsize’,16,’fontweight’,’bold’);
axis([-5,5,-5,5])
set(gcf,’paperpositionmode’,’manual’,’paperposition’,[0.250.251212])
print-dpng../../words/figs/C4/C4S4figure7.png