This action might not be possible to undo. Are you sure you want to continue?
NavierStokes equations on rectangular domains
mit18086 navierstokes.m
Benjamin Seibold
Applied Mathematics
Massachusetts Institute of Technology
wwwmath.mit.edu/~seibold
seibold@math.mit.edu
March 31, 2008
1 Introduction
On the following pages you ﬁnd a documentation for the Matlab program
mit18086 navierstokes.m, as it is used for Course 18.086: Computational Science and En
gineering II at the Massachusetts Institute of Technology. The code can be downloaded from
the Computational Science and Engineering web page http://wwwmath.mit.edu/cse. It
is also linked on the course web page http://wwwmath.mit.edu/18086.
This code shall be used for teaching and learning about incompressible, viscous ﬂows.
It is an example of a simple numerical method for solving the NavierStokes equations. It
contains fundamental components, such as discretization on a staggered grid, an implicit
viscosity step, a projection step, as well as the visualization of the solution over time. The
main priorities of the code are
1. Simplicity and compactness: The whole code is one single Matlab ﬁle of about
100 lines.
2. Flexibility: The code does not use spectral methods, thus can be modiﬁed to more
complex domains, boundary conditions, and ﬂow laws.
3. Visualization: The evolution of the ﬂow ﬁeld is visualized while the simulation runs.
4. Computational speed: Full vectorization and presolving the arising linear systems
in an initialization step results in fast time stepping.
The code provides:
• variable box sizes, grid resolution, time step, and Reynolds numbers
• implicit time stepping for the ﬂuid viscosity
1
• visualization of pressure ﬁeld, velocity ﬁeld and streamlines
• automatic transition from central to donorcell discretization for the nonlinear advec
tion part
• fast computation of the timedependent solution for small to moderate mesh sizes
The code does not provide:
• 3d
• unstructured meshes or complex geometries
• timedependent geometries
• adaptivity, such as local mesh reﬁnement, time step control, etc.
• nonconstant viscosity or density
• higher order time stepping
• turbulence models
• time and memory eﬃciency for large computations
The code qualiﬁes as a basis for modiﬁcations and extensions. The following extensions
have already been applied to the code by MIT students and other users:
• external forces
• inﬂow and outﬂow boundaries
• addition of a drag region
• geometry change to a backwards facing step
• time dependent geometries
• coupling with an advectiondiﬀusion equation
2 Incompressible NavierStokes Equations
We consider the incompressible NavierStokes equations in two space dimensions
u
t
+p
x
= −(u
2
)
x
−(uv)
y
+
1
Re
(u
xx
+u
yy
) (1)
v
t
+p
y
= −(uv)
x
−(v
2
)
y
+
1
Re
(v
xx
+v
yy
) (2)
u
x
+v
y
= 0 (3)
2
on a rectangular domain Ω = [0, l
x
]×[0, l
y
]. The four domain boundaries are denoted North,
South, West, and East. The domain is ﬁxed in time, and we consider noslip boundary
conditions on each wall, i.e.
u(x, l
y
) = u
N
(x) v(x, l
y
) = 0 (4)
u(x, 0) = u
S
(x) v(x, 0) = 0 (5)
u(0, y) = 0 v(0, y) = v
W
(y) (6)
u(l
x
, y) = 0 v(l
x
, y) = v
E
(y) (7)
A derivation of the NavierStokes equations can be found in [2]. The momentum equations
(1) and (2) describe the time evolution of the velocity ﬁeld (u, v) under inertial and viscous
forces. The pressure p is a Lagrange multiplier to satisfy the incompressibility condition
(3). Note that the momentum equations are already put into a numericsfriendly form. The
nonlinear terms on the right hand side equal
(u
2
)
x
+ (uv)
y
= uu
x
+vu
y
(8)
(uv)
x
+ (v
2
)
y
= uv
x
+vv
y
(9)
which follows by the chain rule and equation (3). The above right hand side is often written
in vector form as (u · ∇)u. We choose to numerically discretize the form on the left hand
side, because it is closer to a conservation form.
The incompressibility condition is not a time evolution equation, but an algebraic condi
tion. We incorporate this condition by using a projection approach [1]: Evolve the momen
tum equations neglecting the pressure, then project onto the subspace of divergencefree
velocity ﬁelds.
3 Visualization
Every ﬁxed number of time steps the current pressure and velocity ﬁeld are visualized.
The pressure ﬁeld is shown as a color plot with some contour lines. On top of this, the
normalized velocity ﬁeld is shown as a quiver plot, i.e. little arrows indicate the direction of
the ﬂow. Since in a lid driven cavity the ﬂow rate varies signiﬁcantly over diﬀerent areas,
outputting the normalized velocity ﬁeld is a common procedure. Additionally, stream lines
are shown. Those are paths particles would take in the ﬂow if the velocity ﬁeld was frozen
at the current instant in time. Since the velocity ﬁeld is divergencefree, the streamlines are
closed. The stream lines are contour lines of the stream function q. It is a function whose
orthogonal gradient is the velocity ﬁeld
(∇q)
⊥
= u ⇐⇒ −q
y
= u and q
x
= v (10)
Applying the 2dcurl to this equation yields
−∆q = ∇×(∇q)
⊥
= ∇×u ⇐⇒ −∆q = −q
yy
−q
xx
= u
y
−v
x
(11)
The stream function exists since the compatibility condition ∇· u = u
x
+v
y
= 0 is satisﬁed.
3
4 Numerical Solution Approach
The general approach of the code is described in Section 6.7 in the book Computational
Science and Engineering [4].
While u, v, p and q are the solutions to the NavierStokes equations, we denote the
numerical approximations by capital letters. Assume we have the velocity ﬁeld U
n
and V
n
at the n
th
time step (time t), and condition (3) is satisﬁed. We ﬁnd the solution at the
(n + 1)
st
time step (time t + ∆t) by the following three step approach:
1. Treat nonlinear terms
The nonlinear terms are treated explicitly. This circumvents the solution of a nonlinear
system, but introduces a CFL condition which limits the time step by a constant times
the spacial resolution.
U
∗
−U
n
∆t
= −((U
n
)
2
)
x
−(U
n
V
n
)
y
(12)
V
∗
−V
n
∆t
= −(U
n
V
n
)
x
−((V
n
)
2
)
y
(13)
In Section 5 we will detail how to discretize the nonlinear terms.
2. Implicit viscosity
The viscosity terms are treated implicitly. If they were treated explicitly, we would
have a time step restriction proportional to the spacial discretization squared. We
have no such limitation for the implicit treatment. The price to pay is two linear
systems to be solved in each time step.
U
∗∗
−U
∗
∆t
=
1
Re
(U
∗∗
xx
+U
∗∗
yy
) (14)
V
∗∗
−V
∗
∆t
=
1
Re
(V
∗∗
xx
+V
∗∗
yy
) (15)
3. Pressure correction
We correct the intermediate velocity ﬁeld (U
∗∗
, V
∗∗
) by the gradient of a pressure
P
n+1
to enforce incompressibility.
U
n+1
−U
∗∗
∆t
= −(P
n+1
)
x
(16)
V
n+1
−V
∗∗
∆t
= −(P
n+1
)
y
(17)
The pressure is denoted P
n+1
, since it is only given implicitly. It is obtained by solving
a linear system. In vector notation the correction equations read as
1
∆t
U
n+1
−
1
∆t
U
n
= −∇P
n+1
(18)
Applying the divergence to both sides yields the linear system
−∆P
n+1
= −
1
∆t
∇· U
n
(19)
Hence, the pressure correction step is
4
(a) Compute F
n
= ∇· U
n
(b) Solve Poisson equation −∆P
n+1
= −
1
∆t
F
n
(c) Compute G
n+1
= ∇P
n+1
(d) Update velocity ﬁeld U
n+1
= U
n
−∆tG
n+1
The question, which boundary conditions are appropriate for the Poisson equation
for the pressure P, is complicated. A standard approach is to prescribe homoge
neous Neumann boundary conditions for P wherever noslip boundary conditions are
prescribed for the velocity ﬁeld. For the lid driven cavity problem this means that
homogeneous Neumann boundary conditions are prescribed everywhere. This implies
in particular that the pressure P is only deﬁned up to a constant, which is ﬁne, since
only the gradient of P enters the momentum equation.
In addition to the solution steps, we have the visualization step, in which the stream function
Q
n
is computed. Similarly to the pressure is is obtained by the following steps
1. Compute F
n
= (V
n
)
x
−(U
n
)
y
2. Solve Poisson equation −∆Q
n
= −F
n
We prescribe homogeneous Dirichlet boundary conditions.
5 Spacial Discretization
The spacial discretization is performed on a staggered grid with the pressure P in the cell
midpoints, the velocities U placed on the vertical cell interfaces, and the velocities V placed
on the horizontal cell interfaces. The stream function Q is deﬁned on the cell corners.
Consider to have n
x
×n
y
cells. Figure 1 shows a staggered grid with n
x
= 5 and n
y
= 3.
When speaking of the ﬁelds P, U and V (and Q), care has to be taken about interior and
boundary points. Any point truly inside the domain is an interior point, while points on or
outside boundaries are boundary points. Dark markers in Figure 1 stand for interior points,
while light markers represent boundary points. The ﬁelds have the following sizes:
ﬁeld quantity interior resolution resolution with boundary points
pressure P n
x
×n
y
(n
x
+ 2) ×(n
y
+ 2)
velocity component U (n
x
−1) ×n
y
(n
x
+ 1) ×(n
y
+ 2)
velocity component V n
x
×(n
y
−1) (n
x
+ 2) ×(n
y
+ 1)
stream function Q (n
x
−1) ×(n
y
−1) (n
x
+ 1) ×(n
y
+ 1)
The values at boundary points are no unknown variables. For Dirichlet boundary conditions
they are prescribed, and for Neumann boundry conditions they can be expressed in term
of interior points. However, boundary points of U and V are used for the ﬁnite diﬀerence
approximation of the nonlinear advection terms. Note that the boundary points in the four
corner are never used.
5
U
V
P
Figure 1: Staggered grid with boundary cells
5.1 Approximating derivatives
• Second derivatives
Finite diﬀerences can approximate second derivatives in a grid point by a centered
stencil. At an interior point U
i,j
we approximate the Laplace operator by
∆U
i,j
= (U
xx
)
i,j
+ (U
yy
)
i,j
≈
U
i−1,j
−2U
i,j
+U
i+1,j
h
2
x
+
U
i,j−1
−2U
i,j
+U
i,j+1
h
2
y
(20)
Here one or two of the neighboring points might be boundary points. The same
formula holds for the component V , and for the Laplacian of the pressure P and
the stream function Q. If the unknown quantity is stored in a large column vector,
then the above approximation can be represented as a large sparse block matrix being
applied from the left. Thus, solving the Poisson equations for P and Q, as well as
solving implicitly for the viscosity terms in U and V , yields sparse linear systems to
be solved, as detailed in Section 7.
• First derivatives
A ﬁrst derivative in a grid point can be approximated by a centered stencil.
(U
x
)
i,j
≈
U
i+1,j
−U
i−1,j
2h
x
(21)
6
This, however, can yield instabilities, as shown in many textbooks on numerical anal
ysis. Here the staggered grid comes into play. Assume, we are not interested in the
value of U
x
in the position of U
i,j
, but instead we want the value in the middle between
the points U
i+1,j
and U
i,j
. Then the approximation
(U
x
)
i+
1
2
,j
≈
U
i+1,j
−U
i,j
h
x
(22)
is a stable centered approximation to U
x
in the middle between the two points. In
the staggered grid this position happens to be the position of P
i,j
.
– Pressure correction
In the pressure correction, the approximation of ﬁrst derivatives on a staggered
grid works out perfectly:
1. The divergence of the velocity ﬁeld F = ∇· U computes U
x
and V
y
. Both
values then live in the cell centers, i.e. they can be added directly.
2. For the pressure Poisson equation −∆P = −
1
∆t
F, both sides are deﬁned in
the cell centers, and −∆P can be approximated as described above.
3. The gradient of the pressure G = ∇P requires the computation of P
x
and
P
y
. Again, a look at Figure 1 indicates that the former then live at the
position of U, while the latter live at the positions of V . Exactly where both
are needed to update the velocity ﬁeld.
– Stream function
Similarly, the staggered grid works ﬁne for the stream function. Both V
x
and U
y
live on the cell corners, so the Poisson right hand side F = V
x
−U
y
and thus the
stream function Q lives at the cell corners.
– Nonlinear terms (central diﬀerencing)
The nonlinear terms are the only place where the discretization on the staggered
grid does not work directly. For instance, the product UV is not directly deﬁned,
since U and V live in diﬀerent positions. The solution is to take the arguments
backwards: For updating U, we need (U
2
)
x
and (UV )
y
. If the ﬂow in each time
step is comparably slow, we wish to use the same centered staggered derivatives
as before. This requires U
2
to be deﬁned in the cell centers, and UV to the deﬁned
in the cell corners. We obtain these quantities by interpolating two neighboring
values.
(U
2
)
i+
1
2
,j
=
_
U
i,j
+U
i+1,j
2
_
2
(23)
U
i,j+
1
2
=
U
i,j
+U
i,j+1
2
(24)
V
i+
1
2
,j
=
V
i,j
+V
i+1,j
2
(25)
Analogously for the component V . The index notation lets this idea look more
complicated than it is. All we do is create new data between two points by av
eraging. Using an overbar with superscript h to indicate a horizontally averaged
7
quantity, and an overbar with superscript v to indicate a vertically averaged
quantity, we can write the update for the nonlinear terms as
U
∗
−U
∆t
= −((
¯
U
h
)
2
)
x
−(
¯
U
v
¯
V
h
)
y
(26)
V
∗
−V
∆t
= −(
¯
U
v
¯
V
h
)
x
−((
¯
V
v
)
2
)
y
(27)
– Nonlinear terms (upwinding)
The above centered diﬀerencing is appropriate if quantities are not transported
too far in each time step. For faster ﬂows or larger time steps, the discretization
shall be closer to an upwinding approach. We implement a smooth transition
between centered diﬀerencing and upwinding using a parameter γ ∈ [0, 1]. We
deﬁne it as
γ = min
_
1.2 · ∆t · max
_
max
i,j
U
i,j
, max
i,j
V
i,j

_
, 1
_
(28)
The value of gamma is the maximum fraction of a cells which information can
travel in one time step, multiplied by 1.2, and capped by 1. The factor of 1.2 is
taken from the experience that often times tending a bit more towards upwinding
can be advantageous for accuracy [3].
The linear combination between centered diﬀerencing and upwinding is imple
mented in the following way. In corresponence to the averaged quantities, we
deﬁne diﬀerenced quantities
(
˜
U
h
)
i+
1
2
,j
=
U
i+1,j
−U
i,j
2
(29)
(
˜
U
v
)
i,j+
1
2
=
U
i,j+1
−U
i,j
2
(30)
and analogously for
˜
V
h
and
˜
V
v
. Using the linear combination, equations (26)
and (27) generalize to
U
∗
−U
∆t
= −
_
(
¯
U
h
)
2
−γ
¯
U
h

˜
U
h
_
x
−
_
(
¯
U
v
¯
V
h
) −γ
¯
V
h

˜
U
v
_
y
(31)
V
∗
−V
∆t
= −
_
(
¯
U
v
¯
V
h
) −γ
¯
U
v

˜
V
h
_
x
−
_
(
¯
V
v
)
2
−γ
¯
V
v

˜
V
v
_
y
(32)
One can check the approximation values, as for instance for the U
2
term:
_
(
¯
U
h
)
2
−γ
¯
U
h

˜
U
h
_
i+
1
2
,j
= 
¯
U
h

_

¯
U
h
 −γ
˜
U
h
_
i+
1
2
,j
(33)
=
¯
U
h
_
_
_
_
1−γ
2
_
U
i+1,j
+
_
1+γ
2
_
U
i,j
if
¯
U
h
≥ 0
_
1+γ
2
_
U
i+1,j
+
_
1−γ
2
_
U
i,j
if
¯
U
h
< 0
(34)
One can easily see that this becomes averaged central diﬀerencing for γ = 0 and
conservative upwinding for γ = 1.
8
5.2 Boundary conditions
In the lid driven cavity problem we provide Dirichlet boundary conditions for U and V , and
Neumann boundary conditions for P. Applying the correct boundary conditions requires
care, since for the staggered grid some points lie on a boundary while others have a boundary
between them. At the points that lie on the boundary the value is directly prescribed, such
as U at the west and east boundary, and V at the north and south boundary. For U at the
north and south boundary and for V at west and east boundary, one has to deﬁne a value
between two data points. The idea is the same as above: average the values of two points.
For instance, the north boundary lies between points with velocity U. Let the two points
below respectively above the boundary be U
i,j
and U
i,j+1
, and let the prescribed boundary
value be U
N
. Then the boundary condition is
U
i,j
+U
i,j+1
2
= U
N
⇐⇒ U
i,j
+U
i,j+1
= 2U
N
(35)
Analogously at the south boundary, and for V at the west and east boundary.
The normal derivative
∂P
∂n
at the boundary is deﬁned using two points which have the
boundary in their middle. For instance, at the north boundary, prescribing homogeneous
Neumann boundary conditions yields
P
i,j+1
−P
i,j
h
y
= 0 ⇐⇒ P
i,j+1
= P
i,j
(36)
The stream function is deﬁned on cell boundary points. Thus all its boundary points lie
on the domain boundary. We prescibe homogeneous Dirichlet boundary conditions, which
can be prescribed directly.
6 Solving the Linear Systems
The pressure correction and the implicit discretization of the viscosity terms requires linear
systems to be solved in every time step. Additionally, the computation of the stream
function requires another system to be solved whenever the data is plotted. Since neither
geometry nor discretization change with time, the corresponding system matrices remain the
same in every step. This means that all matrices can be constructed in an initialization step.
Of course, one would would even wish to compute the inverse matrices in an initialization
step, but even for medium grid resolutions these could not be saved, since they are full
matrices. Of the many possible approaches to do at least some work in the initialization,
we propose the following three:
• Use Fourier methods based on the fast Fourier transform in the solution step. Initialize
memory and constants in the setup phase.
• Compute good preconditioners in the setup phase. Candidates are ILU or multigrid.
Save the preconditioners as sparse matrices and use them in the solution phase.
• Use elimination with reordering to compute the inverse matrices exactly, but in a
comparably sparse format.
9
In the code the third approach is implemented. Since the matrices are symmetric positive
deﬁnite, the sparse Cholesky decomposition can be used.
7 Implementation in Matlab
We take advantage of the Matlab data structures and save the ﬁeld quantities as matrices.
Each quantity is stored without boundary points, yielding matrices of the following sizes.
quantity matrix size
U (n
x
−1) ×(n
y
+ 1)
V (n
x
+ 1) ×(n
y
−1)
P n
x
×n
y
Q (n
x
−1) ×(n
y
−1)
In solving for P and Q, as well as for the viscosity part for U and V , the boundary conditions
are brought to the right hand side. The only time boundary values are used explicitly is
when evaluating the nonlinear terms. Here, we extend the matrices U and V to matrices
containing also the boundary points.
7.1 Updates in matrix form
Approximating derivatives can be done in matrix form using the command diff. If P
is a matrix of values living in the cell centers (size n
x
× n
y
), then diff(P)/hx yields a
matrix approximating P
x
(size (n
x
− 1) × n
y
) whose values live on the vertical cell edges.
Analogously, diff(P’)’/hy yields a matrix approximating P
y
(size n
x
× (n
y
− 1)) whose
values live on the horizontal cell edges. Similarly, we deﬁne the function avg, which averages
in the horizontal direction, i.e. avg(P) yields an (n
x
− 1) × n
y
matrix whose values are
horizontally averaged, and avg(P’)’ yields an n
x
×(n
y
−1) matrix whose values are vertically
averaged. Using diff and avg, we can write the updating steps as follows:
• Treat nonlinear terms
First we extend the velocity matrices by rows and columns of boundary points.
Ue = [uW;U;uE]; Ue = [2*uS’Ue(:,1) Ue 2*uN’Ue(:,end)];
Ve = [vS’ V vN’]; Ve = [2*vWVe(1,:);Ve;2*vEVe(end,:)];
The boundary points which fall onto a boundary are concatenated directly. The
values of the boundary points half a meshsize outside of the boundary are computed
using relation (35). These extended matrices U
e
and V
e
are used to proceed further.
Compute (UV )
x
and (UV )
y
by averaging U vertically and V horizontally, and using
the transition parameter γ:
Ua = avg(Ue’)’; Ud = diff(Ue’)’/2;
Va = avg(Ve); Vd = diff(Ve)/2;
UVx = diff(Ua.*Vagamma*abs(Ua).*Vd)/hx;
UVy = diff((Ua.*Vagamma*Ud.*abs(Va))’)’/hy;
10
Compute (U
2
)
x
and (V
2
)
y
by averaging U horizontally and V vertically:
Ua = avg(Ue(:,2:end1)); Ud = diff(Ue(:,2:end1))/2;
Va = avg(Ve(2:end1,:)’)’; Vd = diff(Ve(2:end1,:)’)’/2;
U2x = diff(Ua.^2gamma*abs(Ua).*Ud)/hx;
V2y = diff((Va.^2gamma*abs(Va).*Vd)’)’/hy;
Update values of interior points:
U = Udt*(UVy(2:end1,:)+U2x);
V = Vdt*(UVx(:,2:end1)+V2y);
• Pressure correction
Compute divergence of the velocity ﬁeld ∇· U:
diff(U(:,2:end1))/hx+diff(V(2:end1,:)’)’/hy
Update values of interior points by −∇P:
U(2:end1,2:end1) = U(2:end1,2:end1)diff(P)/hx;
V(2:end1,2:end1) = V(2:end1,2:end1)diff(P’)’/hy;
• Stream function
Compute curl of the velocity ﬁeld ∇×U:
diff(U’)’/hydiff(V)/hx
7.2 Linear Solves
To access the ﬁeld quantities by a linear combination we transform them into a long column
vector using the command reshape. Multiplying a large sparse block matrix from the left
yields the desired linear combination. Afterward the column vector is reshaped back into
the appropriate matrix size. These steps are done whenever linear systems are solved:
• Implicit viscosity
Consider interior points only. Add appropriate boundary values (for implicit viscosity
step). Reshape. Solve linear system. Reshape and update interior points:
rhs = reshape(U(2:end1,2:end1)+Ubc,[],1);
u(peru) = Ru\(Rut\rhs(peru));
U(2:end1,2:end1) = reshape(u,nx1,ny);
• Pressure correction
Compute right hand side in matrix form. Reshape. Solve linear system. Reshape
back and update interior points:
11
rhs = reshape(diff(U(:,2:end1))/hx+diff(V(2:end1,:)’)’/hy,[],1);
p(perp) = Rp\(Rpt\rhs(perp));
P = reshape(p,nx,ny);
U(2:end1,2:end1) = U(2:end1,2:end1)diff(P)/hx;
V(2:end1,2:end1) = V(2:end1,2:end1)diff(P’)’/hy;
• Stream function
Compute right hand side in matrix form. Reshape. Solve linear system. Reshape
back:
rhs = reshape(diff(U’)’/hydiff(V)/hx,[],1);
q(perq) = Rq\(Rqt\rhs(perq));
Q = zeros(nx+1,ny+1);
Q(2:end1,2:end1) = reshape(q,nx1,ny1);
For visualization purposes, the homogeneous Dirichlet boundary points are included
in the matrix Q.
7.3 System matrices
The Laplace operator with appropriate boundary conditions is discretized in the system
matrices Lp, Lu, Lv and Lq. The matrices act on the corresponding ﬁeld quantities P, U, V
and Q, all in column vector shape. Since we use the sparse Cholesky presolve step, solving
the system may look cumbersome. It is not. In principle (yet not eﬃcient), the pressure
correction could be computed as simple as
p = Lp\rhs;
All information required is contained in the four matrices themselves. They are constructed
in the initialization step. Since the unknowns are reshaped into a long column vector
row by row, we can construct the block matrices using the kron command: Let K1x be a
tridiagonal matrix approximating −
∂
2
∂x
2
, and K1y a matrix approximating −
∂
2
∂y
2
, both in one
space dimension. Then the two dimensional Laplace matrix, approximating −
∂
2
∂x
2
−
∂
2
∂y
2
is
obtained by
kron(speye(ny),K1x)+kron(K1y,speye(nx))
This is it. Only care has to be taken to use the correct boundary conditions in the 1d
matrices. We provide the function K1 which generates the matrix
K
1
=
1
h
2
_
_
_
_
_
_
_
a
11
−1
−1 2 −1
.
.
.
.
.
.
.
.
.
−1 2 −1
−1 a
11
_
_
_
_
_
_
_
(37)
The choice of the parameter a
11
allows three kinds of boundary conditions, all of which can
be derived by inserting the boundary relations into a three point Laplace stencil:
12
a
11
type of boundary condition
1 Neumann
2 Dirichlet for point on the boundary
3 Dirichlet for boundary between two points
This leaves us with one small detail: We prescribe Neumann boundary conditions for P.
Hence, the matrix Lp is of corank 1. Its nullspace is N(Lp) = span(e), where e = (1, . . . , 1)
T
.
Since Lp is symmetric, its range is R(Lp) = {
b : e
T
b = 0}. The right hand side is in the range
of Lp by construction of the projection step. In order to perform a Cholesky factorization,
we modify Lp so that it becomes a regular matrix, while still yielding a correct solution for
the pressure. This is achieved by adding 1 to the last entry. The proof is as follows.
Let w = (0, . . . , 0, 1)
T
. Thus w w
T
is a matrix with its only nonzero entry being a 1 in
the last position. Let A be the NeumannPoisson matrix, i.e. Ae = 0. The new modiﬁed
Poisson matrix is B = A+ w w
T
. Let u be an arbitrary vector. Then
Bu = Au
.¸¸.
⊥e
+( w
T
u) w
.¸¸.
⊥e
. (38)
This sum can only equal 0 if u = 0. Hence B has full rank. It remains to show that for any
right hand side
b, which is admissible (i.e.
b ⊥ e), the solution to Bu =
b satisﬁes Au =
b.
First note that due to (38), we have B
−1
w = e. Hence, we get
AB
−1
= (B − w w
T
)B
−1
= I − w w
T
B
−1
= I − we
T
,
and consequently AB
−1
b =
b.
7.4 Presolve with sparse Cholesky
Instead of solving the full system
p = Lp\rhs;
in each time step, we compute a Cholesky matrix in an initialization step. A plain Cholesky
matrix would have many nonzero entries. We use a reordering of the unknowns to minimize
the amount of ﬁllin due to elimination steps. A good permutation of the unknown with
respect to elimination for symmetric matrices is obtained by the command symamd. The
index permutation is stored in a permutation vector. The Cholesky decomposition of the
reordered (rows and columns) system matrix is computed. Finally, to prevent Matlab from
allocating memory in the solution phase we store also the transposed Cholesky matrix to
gain extra speed.
perp = symamd(Lp);
Rp = chol(Lp(perp,perp));
Rpt = Rp’;
In the solution step, the system is solved by a backward and a forward solution step,
applied to the reordered right hand side. The inverse reordering is obtained by applying
the permutation vector to the left hand side:
p(perp) = Rp\(Rpt\rhs(perp));
13
8 Matlab Code
The code can be downloaded from http://wwwmath.mit.edu/18086 and
http://wwwmath.mit.edu/cse
function mit18086_navierstokes
%MIT18086_NAVIERSTOKES
% Solves the incompressible NavierStokes equations in a
% rectangular domain with prescribed velocities along the
% boundary. The solution method is finite differencing on
% a staggered grid with implicit diffusion and a Chorin
% projection method for the pressure.
% Visualization is done by a colormapisoline plot for
% pressure and normalized quiver and streamline plot for
% the velocity field.
% The standard setup solves a lid driven cavity problem.
% 07/2007 by Benjamin Seibold
% http://wwwmath.mit.edu/~seibold/
% Feel free to modify for teaching and learning.
%
Re = 1e2; % Reynolds number
dt = 1e2; % time step
tf = 4e0; % final time
lx = 1; % width of box
ly = 1; % height of box
nx = 90; % number of xgridpoints
ny = 90; % number of ygridpoints
nsteps = 10; % number of steps with graphic output
%
nt = ceil(tf/dt); dt = tf/nt;
x = linspace(0,lx,nx+1); hx = lx/nx;
y = linspace(0,ly,ny+1); hy = ly/ny;
[X,Y] = meshgrid(y,x);
%
% initial conditions
U = zeros(nx1,ny); V = zeros(nx,ny1);
% boundary conditions
uN = x*0+1; vN = avg(x)*0;
uS = x*0; vS = avg(x)*0;
uW = avg(y)*0; vW = y*0;
uE = avg(y)*0; vE = y*0;
%
Ubc = dt/Re*([2*uS(2:end1)’ zeros(nx1,ny2) 2*uN(2:end1)’]/hx^2+...
[uW;zeros(nx3,ny);uE]/hy^2);
Vbc = dt/Re*([vS’ zeros(nx,ny3) vN’]/hx^2+...
[2*vW(2:end1);zeros(nx2,ny1);2*vE(2:end1)]/hy^2);
fprintf(’initialization’)
Lp = kron(speye(ny),K1(nx,hx,1))+kron(K1(ny,hy,1),speye(nx));
Lp(1,1) = 3/2*Lp(1,1);
perp = symamd(Lp); Rp = chol(Lp(perp,perp)); Rpt = Rp’;
Lu = speye((nx1)*ny)+dt/Re*(kron(speye(ny),K1(nx1,hx,2))+...
kron(K1(ny,hy,3),speye(nx1)));
peru = symamd(Lu); Ru = chol(Lu(peru,peru)); Rut = Ru’;
14
Lv = speye(nx*(ny1))+dt/Re*(kron(speye(ny1),K1(nx,hx,3))+...
kron(K1(ny1,hy,2),speye(nx)));
perv = symamd(Lv); Rv = chol(Lv(perv,perv)); Rvt = Rv’;
Lq = kron(speye(ny1),K1(nx1,hx,2))+kron(K1(ny1,hy,2),speye(nx1));
perq = symamd(Lq); Rq = chol(Lq(perq,perq)); Rqt = Rq’;
fprintf(’, time loop\n20%%40%%60%%80%%100%%\n’)
for k = 1:nt
% treat nonlinear terms
gamma = min(1.2*dt*max(max(max(abs(U)))/hx,max(max(abs(V)))/hy),1);
Ue = [uW;U;uE]; Ue = [2*uS’Ue(:,1) Ue 2*uN’Ue(:,end)];
Ve = [vS’ V vN’]; Ve = [2*vWVe(1,:);Ve;2*vEVe(end,:)];
Ua = avg(Ue’)’; Ud = diff(Ue’)’/2;
Va = avg(Ve); Vd = diff(Ve)/2;
UVx = diff(Ua.*Vagamma*abs(Ua).*Vd)/hx;
UVy = diff((Ua.*Vagamma*Ud.*abs(Va))’)’/hy;
Ua = avg(Ue(:,2:end1)); Ud = diff(Ue(:,2:end1))/2;
Va = avg(Ve(2:end1,:)’)’; Vd = diff(Ve(2:end1,:)’)’/2;
U2x = diff(Ua.^2gamma*abs(Ua).*Ud)/hx;
V2y = diff((Va.^2gamma*abs(Va).*Vd)’)’/hy;
U = Udt*(UVy(2:end1,:)+U2x);
V = Vdt*(UVx(:,2:end1)+V2y);
% implicit viscosity
rhs = reshape(U+Ubc,[],1);
u(peru) = Ru\(Rut\rhs(peru));
U = reshape(u,nx1,ny);
rhs = reshape(V+Vbc,[],1);
v(perv) = Rv\(Rvt\rhs(perv));
V = reshape(v,nx,ny1);
% pressure correction
rhs = reshape(diff([uW;U;uE])/hx+diff([vS’ V vN’]’)’/hy,[],1);
p(perp) = Rp\(Rpt\rhs(perp));
P = reshape(p,nx,ny);
U = Udiff(P)/hx;
V = Vdiff(P’)’/hy;
% visualization
if floor(25*k/nt)>floor(25*(k1)/nt), fprintf(’.’), end
if k==1floor(nsteps*k/nt)>floor(nsteps*(k1)/nt)
% stream function
rhs = reshape(diff(U’)’/hydiff(V)/hx,[],1);
q(perq) = Rq\(Rqt\rhs(perq));
Q = zeros(nx+1,ny+1);
Q(2:end1,2:end1) = reshape(q,nx1,ny1);
clf, contourf(avg(x),avg(y),P’,20,’w’), hold on
contour(x,y,Q’,20,’k’);
Ue = [uS’ avg([uW;U;uE]’)’ uN’];
Ve = [vW;avg([vS’ V vN’]);vE];
Len = sqrt(Ue.^2+Ve.^2+eps);
quiver(x,y,(Ue./Len)’,(Ve./Len)’,.4,’k’)
hold off, axis equal, axis([0 lx 0 ly])
p = sort(p); caxis(p([8 end7]))
15
title(sprintf(’Re = %0.1g t = %0.2g’,Re,k*dt))
drawnow
end
end
fprintf(’\n’)
%=======================================================================
function B = avg(A,k)
if nargin<2, k = 1; end
if size(A,1)==1, A = A’; end
if k<2, B = (A(2:end,:)+A(1:end1,:))/2; else, B = avg(A,k1); end
if size(A,2)==1, B = B’; end
function A = K1(n,h,a11)
% a11: Neumann=1, Dirichlet=2, Dirichlet mid=3;
A = spdiags([1 a11 0;ones(n2,1)*[1 2 1];0 a11 1],1:1,n,n)’/h^2;
Acknowledgments
The author is thankful to PerOlof Persson and JeanChristophe Nave for their useful com
ments, which helped make the code more eﬃcient, and to Gilbert Strang for his helpful
remarks on notation and presentation.
References
[1] A.J. Chorin, Numerical solution of the NavierStokes equations. Math. Comput. 22,
745–762, 1968.
[2] A.J. Chorin, J.E. Marsden, A mathematical introduction to ﬂuid mechanics. Third
edition, Springer, 2000.
[3] M. Griebel, T. Dornseifer, T. Neunhoeﬀer, Numerical simulation in ﬂuid dynamics: A
practical introduction. Society for Industrial and Applied Mathematics, Philadelphia,
PA, USA, 1998.
[4] G. Strang, Computational Science and Engineering, First Edition. Wellesley
Cambridge Press, 2007.
16
• nonconstant viscosity or density • higher order time stepping • turbulence models • time and memory eﬃciency for large computations The code qualiﬁes as a basis for modiﬁcations and extensions. The following extensions have already been applied to the code by MIT students and other users: • external forces • inﬂow and outﬂow boundaries • addition of a drag region • geometry change to a backwards facing step • time dependent geometries • coupling with an advectiondiﬀusion equation 2 Incompressible NavierStokes Equations We consider the incompressible NavierStokes equations in two space dimensions 1 (uxx + uyy ) Re 1 vt + py = −(uv)x − (v 2 )y + (vxx + vyy ) Re ux + vy = 0 ut + px = −(u2 )x − (uv)y + 2 (1) (2) (3) . time step control. such as local mesh reﬁnement.• visualization of pressure ﬁeld. velocity ﬁeld and streamlines • automatic transition from central to donorcell discretization for the nonlinear advection part • fast computation of the timedependent solution for small to moderate mesh sizes The code does not provide: • 3d • unstructured meshes or complex geometries • timedependent geometries • adaptivity. etc.
and we consider noslip boundary conditions on each wall. ly ) = 0 v(x. The stream lines are contour lines of the stream function q. The above right hand side is often written in vector form as (u · )u. because it is closer to a conservation form. i. The pressure p is a Lagrange multiplier to satisfy the incompressibility condition (3). South. West. but an algebraic condition. the normalized velocity ﬁeld is shown as a quiver plot. 0) = 0 v(0. outputting the normalized velocity ﬁeld is a common procedure. v) under inertial and viscous forces. 3 Visualization Every ﬁxed number of time steps the current pressure and velocity ﬁeld are visualized. y) = vE (y) (4) (5) (6) (7) A derivation of the NavierStokes equations can be found in [2]. Since the velocity ﬁeld is divergencefree. y) = 0 v(x. The four domain boundaries are denoted North. Additionally. On top of this. The momentum equations (1) and (2) describe the time evolution of the velocity ﬁeld (u.e. ly ]. The domain is ﬁxed in time. Those are paths particles would take in the ﬂow if the velocity ﬁeld was frozen at the current instant in time. y) = vW (y) v(lx . The nonlinear terms on the right hand side equal (u2 )x + (uv)y = uux + vuy (uv)x + (v )y = uvx + vvy 2 (8) (9) which follows by the chain rule and equation (3). ly ) = uN (x) u(x. and East. Since in a lid driven cavity the ﬂow rate varies signiﬁcantly over diﬀerent areas. then project onto the subspace of divergencefree velocity ﬁelds. stream lines are shown. We choose to numerically discretize the form on the left hand side. The pressure ﬁeld is shown as a color plot with some contour lines. little arrows indicate the direction of the ﬂow. It is a function whose orthogonal gradient is the velocity ﬁeld ( q)⊥ = u ⇐⇒ −qy = u and qx = v (10) Applying the 2dcurl to this equation yields −∆q = × ( q)⊥ = ×u ⇐⇒ −∆q = −qyy − qxx = uy − vx (11) The stream function exists since the compatibility condition 3 · u = ux + vy = 0 is satisﬁed. . i.on a rectangular domain Ω = [0. The incompressibility condition is not a time evolution equation. u(x. y) = 0 u(lx . Note that the momentum equations are already put into a numericsfriendly form. We incorporate this condition by using a projection approach [1]: Evolve the momentum equations neglecting the pressure. lx ]×[0. the streamlines are closed.e. 0) = uS (x) u(0.
the pressure correction step is 4 . U n+1 − U ∗∗ = −(P n+1 )x (16) ∆t V n+1 − V ∗∗ = −(P n+1 )y (17) ∆t The pressure is denoted P n+1 . V ∗∗ ) by the gradient of a pressure P n+1 to enforce incompressibility. (12) (13) 2. Assume we have the velocity ﬁeld U n and V n at the nth time step (time t). If they were treated explicitly. p and q are the solutions to the NavierStokes equations. Pressure correction We correct the intermediate velocity ﬁeld (U ∗∗ . While u. We ﬁnd the solution at the (n + 1)st time step (time t + ∆t) by the following three step approach: 1. U∗ − Un = −((U n )2 )x − (U n V n )y ∆t V∗−Vn = −(U n V n )x − ((V n )2 )y ∆t In Section 5 we will detail how to discretize the nonlinear terms. Treat nonlinear terms The nonlinear terms are treated explicitly. Implicit viscosity The viscosity terms are treated implicitly. v. 1 U ∗∗ − U ∗ ∗∗ = (U ∗∗ + Uyy ) ∆t Re xx 1 V ∗∗ − V ∗ ∗∗ = (V ∗∗ + Vyy ) ∆t Re xx (14) (15) 3. since it is only given implicitly. We have no such limitation for the implicit treatment. The price to pay is two linear systems to be solved in each time step. and condition (3) is satisﬁed. we denote the numerical approximations by capital letters.7 in the book Computational Science and Engineering [4]. This circumvents the solution of a nonlinear system.4 Numerical Solution Approach The general approach of the code is described in Section 6. It is obtained by solving a linear system. we would have a time step restriction proportional to the spacial discretization squared. In vector notation the correction equations read as 1 n+1 1 n U − U = − P n+1 (18) ∆t ∆t Applying the divergence to both sides yields the linear system 1 −∆P n+1 = − · Un (19) ∆t Hence. but introduces a CFL condition which limits the time step by a constant times the spacial resolution.
U and V (and Q). For the lid driven cavity problem this means that homogeneous Neumann boundary conditions are prescribed everywhere. Compute F n = (V n )x − (U n )y 2. and the velocities V placed on the horizontal cell interfaces. For Dirichlet boundary conditions they are prescribed.(a) Compute F n = (c) Compute Gn+1 = · Un P n+1 1 (b) Solve Poisson equation −∆P n+1 = − ∆t F n (d) Update velocity ﬁeld Un+1 = Un − ∆tGn+1 The question. Consider to have nx × ny cells. in which the stream function Qn is computed. while points on or outside boundaries are boundary points. In addition to the solution steps. Dark markers in Figure 1 stand for interior points. is complicated. This implies in particular that the pressure P is only deﬁned up to a constant. since only the gradient of P enters the momentum equation. which boundary conditions are appropriate for the Poisson equation for the pressure P . Similarly to the pressure is is obtained by the following steps 1. and for Neumann boundry conditions they can be expressed in term of interior points. 5 . When speaking of the ﬁelds P . Any point truly inside the domain is an interior point. The ﬁelds have the following sizes: ﬁeld quantity pressure P velocity component U velocity component V stream function Q interior resolution nx × ny (nx − 1) × ny nx × (ny − 1) (nx − 1) × (ny − 1) resolution with boundary points (nx + 2) × (ny + 2) (nx + 1) × (ny + 2) (nx + 2) × (ny + 1) (nx + 1) × (ny + 1) The values at boundary points are no unknown variables. However. which is ﬁne. The stream function Q is deﬁned on the cell corners. we have the visualization step. A standard approach is to prescribe homogeneous Neumann boundary conditions for P wherever noslip boundary conditions are prescribed for the velocity ﬁeld. Note that the boundary points in the four corner are never used. 5 Spacial Discretization The spacial discretization is performed on a staggered grid with the pressure P in the cell midpoints. Figure 1 shows a staggered grid with nx = 5 and ny = 3. boundary points of U and V are used for the ﬁnite diﬀerence approximation of the nonlinear advection terms. care has to be taken about interior and boundary points. Solve Poisson equation −∆Qn = −F n We prescribe homogeneous Dirichlet boundary conditions. the velocities U placed on the vertical cell interfaces. while light markers represent boundary points.
j + (Uyy )i.j Ui.1 Approximating derivatives • Second derivatives Finite diﬀerences can approximate second derivatives in a grid point by a centered stencil.U P V Figure 1: Staggered grid with boundary cells 5.j + Ui+1.j we approximate the Laplace operator by ∆Ui.j − Ui−1. solving the Poisson equations for P and Q. At an interior point Ui. yields sparse linear systems to be solved.j 2hx (21) 6 . If the unknown quantity is stored in a large column vector. Thus.j + Ui. The same formula holds for the component V . as well as solving implicitly for the viscosity terms in U and V . • First derivatives A ﬁrst derivative in a grid point can be approximated by a centered stencil. as detailed in Section 7. then the above approximation can be represented as a large sparse block matrix being applied from the left.j ≈ Ui+1.j ≈ Ui−1. and for the Laplacian of the pressure P and the stream function Q.j − 2Ui.j+1 + (20) 2 hx h2 y Here one or two of the neighboring points might be boundary points.j = (Uxx )i. (Ux )i.j−1 − 2Ui.
j + Ui+1.j . For instance.j and Ui. the staggered grid works ﬁne for the stream function. We obtain these quantities by interpolating two neighboring values. The solution is to take the arguments backwards: For updating U . can yield instabilities.j+1 = 2 Vi. both sides are deﬁned in the cell centers.j + Ui.j . – Stream function Similarly. the approximation of ﬁrst derivatives on a staggered grid works out perfectly: 1. and −∆P can be approximated as described above. we are not interested in the value of Ux in the position of Ui. The gradient of the pressure G = P requires the computation of Px and Py . Using an overbar with superscript h to indicate a horizontally averaged 7 .j = 2 Ui. Exactly where both are needed to update the velocity ﬁeld.j − Ui. For the pressure Poisson equation −∆P = − ∆t F . Both Vx and Uy live on the cell corners.j hx (22) is a stable centered approximation to Ux in the middle between the two points. but instead we want the value in the middle between the points Ui+1. (U 2 )i+ 1 .j + Vi+1. the product U V is not directly deﬁned. Assume.j 2 Ui. 1 2. we need (U 2 )x and (U V )y . This requires U 2 to be deﬁned in the cell centers. Here the staggered grid comes into play. If the ﬂow in each time step is comparably slow.j = 2 2 (23) (24) (25) Analogously for the component V . a look at Figure 1 indicates that the former then live at the position of U .j+ 1 2 Vi+ 1 .j 2 Ui. – Nonlinear terms (central diﬀerencing) The nonlinear terms are the only place where the discretization on the staggered grid does not work directly. as shown in many textbooks on numerical analysis. we wish to use the same centered staggered derivatives as before. The divergence of the velocity ﬁeld F = · U computes Ux and Vy . i. while the latter live at the positions of V . 3. since U and V live in diﬀerent positions. Then the approximation (Ux )i+ 1 . Again. All we do is create new data between two points by averaging. Both values then live in the cell centers. – Pressure correction In the pressure correction. they can be added directly. so the Poisson right hand side F = Vx − Uy and thus the stream function Q lives at the cell corners. however.j ≈ 2 Ui+1.e. The index notation lets this idea look more complicated than it is. In the staggered grid this position happens to be the position of Pi.This.j . and U V to the deﬁned in the cell corners.
we can write the update for the nonlinear terms as U∗ − U ¯ ¯ ¯ = −((U h )2 )x − (U v V h )y ∆t V∗−V ¯ ¯ ¯ = −(U v V h )x − ((V v )2 )y ∆t (26) (27) – Nonlinear terms (upwinding) The above centered diﬀerencing is appropriate if quantities are not transported too far in each time step.j = 2 (29) (30) ˜ ˜ and analogously for V h and V v .j − Ui. multiplied by 1.j 2 1−γ Ui+1. 8 .j .j 2 2 (33) ¯ if U h ≥ 0 ¯ if U h < 0 (34) One can easily see that this becomes averaged central diﬀerencing for γ = 0 and conservative upwinding for γ = 1.j i.j 2 Ui.j = 2 ˜ (U v )i.2 · ∆t · max max Ui. For faster ﬂows or larger time steps.2 is taken from the experience that often times tending a bit more towards upwinding can be advantageous for accuracy [3].j  . In corresponence to the averaged quantities.j (28) The value of gamma is the maximum fraction of a cells which information can travel in one time step. We implement a smooth transition between centered diﬀerencing and upwinding using a parameter γ ∈ [0.2. We deﬁne it as γ = min 1.j + 1−γ Ui. and capped by 1.quantity.j+ 1 2 Ui+1. The factor of 1.j 2 2 ¯ = Uh 1+γ Ui+1. 1 i. equations (26) and (27) generalize to U∗ − U ¯ ¯ ˜ ¯ ¯ ¯ ˜ = − (U h )2 − γU h U h − (U v V h ) − γV h U v ∆t x V∗−V ¯ ¯ ˜ ¯ ˜ ¯ ¯ = − (U v V h ) − γU v V h − (V v )2 − γV v V v ∆t x (31) (32) y y One can check the approximation values. Using the linear combination. as for instance for the U 2 term: ¯ ¯ ˜ (U h )2 − γU h U h i+ 1 . max Vi. the discretization shall be closer to an upwinding approach. we deﬁne diﬀerenced quantities ˜ (U h )i+ 1 . The linear combination between centered diﬀerencing and upwinding is implemented in the following way.j 2 ¯ ¯ ˜ = U h  U h  − γ U h i+ 1 .j+1 − Ui.j + 1+γ Ui. and an overbar with superscript v to indicate a vertically averaged quantity. 1].
j + Ui. at the north boundary. Additionally. such as U at the west and east boundary.j+1 . the corresponding system matrices remain the same in every step. 9 . Then the boundary condition is Ui. 6 Solving the Linear Systems The pressure correction and the implicit discretization of the viscosity terms requires linear systems to be solved in every time step.j+1 = UN 2 ⇐⇒ Ui. Candidates are ILU or multigrid.j+1 = 2UN (35) Analogously at the south boundary. and V at the north and south boundary. Since neither geometry nor discretization change with time. For instance. The idea is the same as above: average the values of two points.j + Ui.j =0 hy ⇐⇒ Pi. and Neumann boundary conditions for P . prescribing homogeneous Neumann boundary conditions yields Pi. Of course. Thus all its boundary points lie on the domain boundary. but even for medium grid resolutions these could not be saved. • Use elimination with reordering to compute the inverse matrices exactly. the computation of the stream function requires another system to be solved whenever the data is plotted. For instance.j+1 = Pi. one has to deﬁne a value between two data points. Initialize memory and constants in the setup phase.j+1 − Pi. since they are full matrices. but in a comparably sparse format.2 Boundary conditions In the lid driven cavity problem we provide Dirichlet boundary conditions for U and V . Applying the correct boundary conditions requires care. • Compute good preconditioners in the setup phase. Save the preconditioners as sparse matrices and use them in the solution phase. Let the two points below respectively above the boundary be Ui.j (36) The stream function is deﬁned on cell boundary points. For U at the north and south boundary and for V at west and east boundary.5. We prescibe homogeneous Dirichlet boundary conditions. which can be prescribed directly. and let the prescribed boundary value be UN . one would would even wish to compute the inverse matrices in an initialization step. Of the many possible approaches to do at least some work in the initialization. This means that all matrices can be constructed in an initialization step. since for the staggered grid some points lie on a boundary while others have a boundary between them. the north boundary lies between points with velocity U . At the points that lie on the boundary the value is directly prescribed. and for V at the west and east boundary.j and Ui. we propose the following three: • Use Fourier methods based on the fast Fourier transform in the solution step. The normal derivative ∂P at the boundary is deﬁned using two points which have the ∂n boundary in their middle.
1 Updates in matrix form Approximating derivatives can be done in matrix form using the command diff. which averages in the horizontal direction. Vd = diff(Ve)/2. diff(P’)’/hy yields a matrix approximating Py (size nx × (ny − 1)) whose values live on the horizontal cell edges. Va = avg(Ve). and using the transition parameter γ: Ua = avg(Ue’)’. UVx = diff(Ua. then diff(P)/hx yields a matrix approximating Px (size (nx − 1) × ny ) whose values live on the vertical cell edges. Analogously. as well as for the viscosity part for U and V . Ve = [2*vWVe(1.uE]. we can write the updating steps as follows: • Treat nonlinear terms First we extend the velocity matrices by rows and columns of boundary points. 7.*Vd)/hx. i.:).In the code the third approach is implemented. we deﬁne the function avg. Ue = [2*uS’Ue(:. the boundary conditions are brought to the right hand side. Using diff and avg. The values of the boundary points half a meshsize outside of the boundary are computed using relation (35).Ve. Ud = diff(Ue’)’/2.1) Ue 2*uN’Ue(:.U. avg(P) yields an (nx − 1) × ny matrix whose values are horizontally averaged. If P is a matrix of values living in the cell centers (size nx × ny ). Since the matrices are symmetric positive deﬁnite.:)]. Ue = [uW. yielding matrices of the following sizes.*Vagamma*abs(Ua). UVy = diff((Ua. 7 Implementation in Matlab We take advantage of the Matlab data structures and save the ﬁeld quantities as matrices.2*vEVe(end. Ve = [vS’ V vN’]. quantity U V P Q matrix size (nx − 1) × (ny + 1) (nx + 1) × (ny − 1) nx × ny (nx − 1) × (ny − 1) In solving for P and Q. Similarly. the sparse Cholesky decomposition can be used.end)]. 10 . The only time boundary values are used explicitly is when evaluating the nonlinear terms. The boundary points which fall onto a boundary are concatenated directly. Compute (U V )x and (U V )y by averaging U vertically and V horizontally.*abs(Va))’)’/hy. we extend the matrices U and V to matrices containing also the boundary points. Each quantity is stored without boundary points.*Vagamma*Ud. These extended matrices U e and V e are used to proceed further.e. and avg(P’)’ yields an nx ×(ny −1) matrix whose values are vertically averaged. Here.
:)+U2x). u(peru) = Ru\(Rut\rhs(peru)). U2x = diff(Ua.Compute (U 2 )x and (V 2 )y by averaging U horizontally and V vertically: Ua = avg(Ue(:. V(2:end1.ny).^2gamma*abs(Va). Reshape and update interior points: rhs = reshape(U(2:end1.^2gamma*abs(Ua).:)’)’/hy Update values of interior points by − P : U(2:end1. Solve linear system.*Ud)/hx.2:end1)+V2y).*Vd)’)’/hy. V2y = diff((Va. • Pressure correction Compute right hand side in matrix form. Va = avg(Ve(2:end1. Reshape. Solve linear system. V = Vdt*(UVx(:.2:end1)diff(P’)’/hy. U(2:end1. Add appropriate boundary values (for implicit viscosity step).1).2:end1)). Vd = diff(Ve(2:end1.[].:)’)’.2:end1)+Ubc.2:end1) = reshape(u.:)’)’/2.2:end1) = U(2:end1. These steps are done whenever linear systems are solved: • Implicit viscosity Consider interior points only.2:end1))/2. • Stream function Compute curl of the velocity ﬁeld diff(U’)’/hydiff(V)/hx × U: 7.2 Linear Solves To access the ﬁeld quantities by a linear combination we transform them into a long column vector using the command reshape.2:end1))/hx+diff(V(2:end1.2:end1) = V(2:end1. • Pressure correction Compute divergence of the velocity ﬁeld · U: diff(U(:.2:end1)diff(P)/hx. Afterward the column vector is reshaped back into the appropriate matrix size. Multiplying a large sparse block matrix from the left yields the desired linear combination. Reshape. Update values of interior points: U = Udt*(UVy(2:end1. Reshape back and update interior points: 11 . Ud = diff(Ue(:.nx1.
2:end1) = U(2:end1. both in one ∂ space dimension.ny).nx.nx1.ny1). Reshape. 7.2:end1))/hx+diff(V(2:end1. Then the two dimensional Laplace matrix. U . and K1y a matrix approximating − ∂y2 . q(perq) = Rq\(Rqt\rhs(perq)). Only care has to be taken to use the correct boundary conditions in the 1d matrices. V and Q. Lv and Lq. Solve linear system.3 System matrices The Laplace operator with appropriate boundary conditions is discretized in the system matrices Lp. approximating − ∂x2 − obtained by 2 ∂2 ∂y 2 is kron(speye(ny).1). we can construct the block matrices using the kron command: Let K1x be a ∂2 ∂2 tridiagonal matrix approximating − ∂x2 . p(perp) = Rp\(Rpt\rhs(perp)). the homogeneous Dirichlet boundary points are included in the matrix Q.speye(nx)) This is it.1). h −1 2 −1 −1 a11 The choice of the parameter a11 allows three kinds of boundary conditions. the pressure correction could be computed as simple as p = Lp\rhs. Lu.:)’)’/hy. For visualization purposes. We provide the function K1 which generates the matrix a11 −1 −1 2 −1 1 . The matrices act on the corresponding ﬁeld quantities P . Since the unknowns are reshaped into a long column vector row by row. .. Since we use the sparse Cholesky presolve step. All information required is contained in the four matrices themselves.. all of which can be derived by inserting the boundary relations into a three point Laplace stencil: 12 .ny+1).[]. Reshape back: rhs = reshape(diff(U’)’/hydiff(V)/hx. K1 = 2 (37) . They are constructed in the initialization step. U(2:end1. P = reshape(p. Q(2:end1.[]. .rhs = reshape(diff(U(:. In principle (yet not eﬃcient).2:end1) = reshape(q..2:end1) = V(2:end1.K1x)+kron(K1y.2:end1)diff(P)/hx. . Q = zeros(nx+1. • Stream function Compute right hand side in matrix form. It is not. V(2:end1. solving the system may look cumbersome. all in column vector shape. .2:end1)diff(P’)’/hy.
0. the system is solved by a backward and a forward solution step.e. Hence. and consequently AB −1 b = b. The inverse reordering is obtained by applying the permutation vector to the left hand side: p(perp) = Rp\(Rpt\rhs(perp)). First note that due to (38). to prevent Matlab from allocating memory in the solution phase we store also the transposed Cholesky matrix to gain extra speed. . 7. . This is achieved by adding 1 to the last entry. its range is R(Lp) = {b : eT b = 0}. It remains to show that for any right hand side b. Then Bu = Au +(wT u) w ⊥e ⊥e . i.perp)). In order to perform a Cholesky factorization. . . the solution to Bu = b satisﬁes Au = b. The Cholesky decomposition of the reordered (rows and columns) system matrix is computed. 13 . we have B −1 w = e. .e. . Finally. 1)T . 1)T . The index permutation is stored in a permutation vector. Let A be the NeumannPoisson matrix. In the solution step. Hence. while still yielding a correct solution for the pressure. where e = (1. . Thus wwT is a matrix with its only nonzero entry being a 1 in the last position. the matrix Lp is of corank 1. in each time step. we compute a Cholesky matrix in an initialization step. We use a reordering of the unknowns to minimize the amount of ﬁllin due to elimination steps. Its nullspace is N (Lp) = span(e). Let u be an arbitrary vector. applied to the reordered right hand side. we get AB −1 = (B − wwT )B −1 = I − wwT B −1 = I − weT . Ae = 0. The proof is as follows. . The right hand side is in the range of Lp by construction of the projection step. Rpt = Rp’. Rp = chol(Lp(perp. Let w = (0. Since Lp is symmetric. we modify Lp so that it becomes a regular matrix. The new modiﬁed Poisson matrix is B = A + wwT . which is admissible (i.4 Presolve with sparse Cholesky Instead of solving the full system p = Lp\rhs. A plain Cholesky matrix would have many nonzero entries. A good permutation of the unknown with respect to elimination for symmetric matrices is obtained by the command symamd. perp = symamd(Lp). (38) This sum can only equal 0 if u = 0.a11 1 2 3 type of boundary condition Neumann Dirichlet for point on the boundary Dirichlet for boundary between two points This leaves us with one small detail: We prescribe Neumann boundary conditions for P . Hence B has full rank. b ⊥ e).
dt = tf/nt. %Re = 1e2. % number of steps with graphic output %nt = ceil(tf/dt).ny+1). vS = avg(x)*0.ny3) vN’]/hx^2+. perp = symamd(Lp). Lp(1. % final time lx = 1. peru = symamd(Lu).lx.1).1).nx+1). uS = x*0.ny).ny1). hy = ly/ny.1) = 3/2*Lp(1. vN = avg(x)*0.K1(nx1.2*vE(2:end1)]/hy^2).speye(nx1))).edu/cse function mit18086_navierstokes %MIT18086_NAVIERSTOKES % Solves the incompressible NavierStokes equations in a % rectangular domain with prescribed velocities along the % boundary... vW = y*0. % width of box ly = 1. [X.Y] = meshgrid(y. %Ubc = dt/Re*([2*uS(2:end1)’ zeros(nx1. The solution method is finite differencing on % a staggered grid with implicit diffusion and a Chorin % projection method for the pressure. % height of box nx = 90..mit.3). fprintf(’initialization’) Lp = kron(speye(ny). Ru = chol(Lu(peru.ly.x)..K1(nx. vE = y*0. % Visualization is done by a colormapisoline plot for % pressure and normalized quiver and streamline plot for % the velocity field.perp)). V = zeros(nx. % 07/2007 by Benjamin Seibold % http://wwwmath.ny2) 2*uN(2:end1)’]/hx^2+. Vbc = dt/Re*([vS’ zeros(nx. % The standard setup solves a lid driven cavity problem. Lu = speye((nx1)*ny)+dt/Re*(kron(speye(ny).speye(nx)).2))+. Rut = Ru’. [uW.hx.mit. % boundary conditions uN = x*0+1.zeros(nx2. [2*vW(2:end1)..edu/~seibold/ % Feel free to modify for teaching and learning. %% initial conditions U = zeros(nx1. % number of xgridpoints ny = 90.edu/18086 and http://wwwmath. uW = avg(y)*0.ny1).8 Matlab Code The code can be downloaded from http://wwwmath. uE = avg(y)*0. kron(K1(ny.uE]/hy^2).hy.. Rp = chol(Lp(perp. Rpt = Rp’.hy. % number of ygridpoints nsteps = 10.zeros(nx3.mit.1))+kron(K1(ny. x = linspace(0.peru)). 14 . % time step tf = 4e0.hx. y = linspace(0. hx = lx/nx. % Reynolds number dt = 1e2.ny).
% implicit viscosity rhs = reshape(U+Ubc.[]. Ve = [2*vWVe(1. Rv = chol(Lv(perv.20.*Vagamma*Ud. V = reshape(v.. U = Udt*(UVy(2:end1.2:end1))/2.1).1).*Vd)/hx.Ve.3))+.hy.^2gamma*abs(Ua).speye(nx))).’k’). Q = zeros(nx+1. time loop\n20%%40%%60%%80%%100%%\n’) for k = 1:nt % treat nonlinear terms gamma = min(1.^2gamma*abs(Va).K1(nx1. hold on contour(x.P’.^2+Ve.end)]. Q(2:end1.perv)). Vd = diff(Ve(2:end1. U = reshape(u.2:end1) = reshape(q.2:end1)+V2y).ny1). v(perv) = Rv\(Rvt\rhs(perv)).2*dt*max(max(max(abs(U)))/hx. % pressure correction rhs = reshape(diff([uW. Len = sqrt(Ue.speye(nx1)).4.1).y. Ud = diff(Ue(:.’w’).avg(y).hx.2). contourf(avg(x).. fprintf(’. rhs = reshape(V+Vbc.2*vEVe(end.Q’. V2y = diff((Va.*abs(Va))’)’/hy. Vd = diff(Ve)/2.:)].perq)). U = Udiff(P)/hx. kron(K1(ny1. quiver(x.uE])/hx+diff([vS’ V vN’]’)’/hy.K1(nx. q(perq) = Rq\(Rqt\rhs(perq)).(Ve.[].’k’) hold off.*Ud)/hx.nx1.uE]’)’ uN’].^2+eps).(Ue.ny).uE]. Rq = chol(Lq(perq. p(perp) = Rp\(Rpt\rhs(perp)).20.ny).[]. U2x = diff(Ua.U. Lq = kron(speye(ny1)./Len)’. Ue = [2*uS’Ue(:. P = reshape(p. fprintf(’.1) Ue 2*uN’Ue(:.max(max(abs(V)))/hy).vE].2). perv = symamd(Lv).’). axis equal. u(peru) = Ru\(Rut\rhs(peru))..2))+kron(K1(ny1.*Vagamma*abs(Ua). Ue = [uW. Ud = diff(Ue’)’/2.U. Ua = avg(Ue(:.Lv = speye(nx*(ny1))+dt/Re*(kron(speye(ny1).:)+U2x). UVy = diff((Ua.U.:)’)’/2./Len)’. axis([0 lx 0 ly]) p = sort(p). Rqt = Rq’. Ve = [vS’ V vN’].:)’)’.avg([vS’ V vN’]).nx.hy. Ua = avg(Ue’)’. Va = avg(Ve(2:end1. perq = symamd(Lq).ny1).2:end1)). UVx = diff(Ua. V = Vdt*(UVx(:.[]. % visualization if floor(25*k/nt)>floor(25*(k1)/nt).nx1. Rvt = Rv’. caxis(p([8 end7])) 15 . Ve = [vW. end if k==1floor(nsteps*k/nt)>floor(nsteps*(k1)/nt) % stream function rhs = reshape(diff(U’)’/hydiff(V)/hx.1).ny+1).y.:).*Vd)’)’/hy.nx. Va = avg(Ve). V = Vdiff(P’)’/hy. clf.1). Ue = [uS’ avg([uW.hx.
T. Strang. Marsden. Acknowledgments The author is thankful to PerOlof Persson and JeanChristophe Nave for their useful comments. 16 .2g’. Third edition. References [1] A. Computational Science and Engineering. which helped make the code more eﬃcient.1)*[1 2 1]. end if size(A.k1).h. Chorin. T. 745–762.title(sprintf(’Re = %0.:)+A(1:end1.:))/2. k = 1. 1998. Dirichlet=2. end function A = K1(n. WellesleyCambridge Press. PA. [4] G.1)==1.a11) % a11: Neumann=1. Society for Industrial and Applied Mathematics. B = B’. USA. B = avg(A. B = (A(2:end.n. [2] A. Chorin.J. end if k<2.n)’/h^2.J.0 a11 1].k*dt)) %======================================================================= function B = avg(A.Re. Neunhoeﬀer. else. A = A’. 2000. J. Numerical simulation in ﬂuid dynamics: A practical introduction. First Edition. Numerical solution of the NavierStokes equations. 22. Dirichlet mid=3.1g drawnow end end fprintf(’\n’) t = %0.2)==1. Dornseifer. 2007. 1968. Math. and to Gilbert Strang for his helpful remarks on notation and presentation.E. A = spdiags([1 a11 0. Springer. Philadelphia. end if size(A. Comput.k) if nargin<2.1:1. A mathematical introduction to ﬂuid mechanics. Griebel.ones(n2. [3] M.
This action might not be possible to undo. Are you sure you want to continue?
We've moved you to where you read on your other device.
Get the full title to continue listening from where you left off, or restart the preview.