1 

2 
\section{Stokes Flow} 
3 
\label{STOKES FLOW CHAP} 
4 

5 
In this section we will look at Computational Fluid Dynamics (CFD) to simulate the flow of fluid under the influence of gravity. The StokesProblemCartesian class will be used to calculate the velocity and pressure of the fluid. 
6 
The fluid dynamics is governed by the Stokes equation. In geophysical problems the velocity of fluids are low; that is, the inertial forces are small compared with the viscous forces, therefore the inertial terms in the NavierStokes equations can be ignored. For a body force, $f$, the governing equations are given by: 
7 
% 
8 
\begin{equation} 
9 
\nabla \cdot (\eta(\nabla \vec{v} + \nabla^{T} \vec{v}))  \nabla p = f, 
10 
\label{GENERAL NAVIER STOKES} 
11 
\end{equation} 
12 
% 
13 
with the incompressibility condition 
14 
% 
15 
\begin{equation} 
16 
\nabla \cdot \vec{v} = 0. 
17 
\label{INCOMPRESSIBILITY} 
18 
\end{equation} 
19 
% 
20 
where $p$, $\eta$ and $f$ are the pressure, viscosity and body forces, respectively. 
21 
Alternatively, the Stokes equations can be represented in Einstein summation tensor notation (compact notation): 
22 
% 
23 
\begin{equation} 
24 
(\eta(v\hackscore{i,j} + v\hackscore{j,i})),\hackscore{j}  p,\hackscore{i} = f\hackscore{i}, 
25 
\label{GENERAL NAVIER STOKES COM} 
26 
\end{equation} 
27 
% 
28 
with the incompressibility condition 
29 
% 
30 
\begin{equation} 
31 
v\hackscore{i,i} = 0. 
32 
\label{INCOMPRESSIBILITY COM} 
33 
\end{equation} 
34 
% 
35 
The subscript comma $i$ denotes the derivative of the function with respect to $x\hackscore{i}$. 
36 
%A linear relationship between the deviatoric stress $\sigma^{'}\hackscore{ij}$ and the stretching $D\hackscore{ij} = \frac{1}{2}(v\hackscore{i,j} + v\hackscore{j,i})$ is defined as \cite{GROSS2006}: 
37 
% 
38 
%\begin{equation} 
39 
%\sigma^{'}\hackscore{ij} = 2\eta D^{'}\hackscore{ij}, 
40 
%\label{STRESS} 
41 
%\end{equation} 
42 
% 
43 
%where the deviatoric stretching $D^{'}\hackscore{ij}$ is defined as 
44 
% 
45 
%\begin{equation} 
46 
%D^{'}\hackscore{ij} = D^{'}\hackscore{ij}  \frac{1}{3}D\hackscore{kk}\delta\hackscore{ij}. 
47 
%\label{DEVIATORIC STRETCHING} 
48 
%\end{equation} 
49 
% 
50 
%where $\delta\hackscore{ij}$ is the Kronecker $\delta$symbol, which is a matrix with ones for its diagonal entries ($i = j$) and zeros for the remaining entries ($i \neq j$). 
51 
The body force $f$ in Equation (\ref{GENERAL NAVIER STOKES COM}) is the gravity acting in the $x\hackscore{3}$ direction and is given as $f = g \rho \delta\hackscore{i3}$. 
52 
The Stokes equations is a saddle point problem, and can be solved using a Uzawa scheme. A class called StokesProblemCartesian in Escript can be used to solve for velocity and pressure; more detail on the class can be view in Chapter \ref{MODELS CHAPTER}. 
53 
In order to keep numerical stability, the timestep size needs to be kept below a certain value, to satisfy the Courant condition. The Courant number is defined as: 
54 
% 
55 
\begin{equation} 
56 
C = \frac{v \delta t}{h}. 
57 
\label{COURANT} 
58 
\end{equation} 
59 
% 
60 
where $\delta t$, $v$, and $h$ are the timestep, velocity, and the width of an element in the mesh, respectively. The velocity $v$ may be chosen as the maximum velocity in the domain. In this problem the timestep size was calculated for a Courant number of 0.4. 
61 

62 
The following PYTHON script is the setup for the Stokes flow simulation, and is available in the example directory as 'fluid.py'. It starts off by importing the classes, such as the StokesProblemCartesian class, for solving the Stokes equation and the incompressibility condition for velocity and pressure. Physical constants are defined for the viscosity and density of the fluid, along with the acceleration due to gravity. Solver settings are set for the maximum iterations and tolerance; the default solver used is PCG. The mesh is defined as a rectangle, to represent the body of fluid. The gravitational force is calculated base on the fluid density and the acceleration due to gravity. The boundary conditions are set for a slip condition at the base of the mesh; fluid movement in the xdirection is free, but fixed in the ydirection. An instance of the StokesProblemCartesian is defined for the given computational mesh, and the solver tolerance set. Inside the while loop, the boundary conditions, viscosity and body force are initialized. The Stokes equation is then solved for velocity and pressure. The timestep size is calculated base on the Courant condition, to ensure stable solutions. The nodes in the mesh are then displaced based on the current velocity and timestep size, to move the body of fluid. The output for the simulation of velocity and pressure is then save to file for visualization. 
63 
% 
64 
\begin{python} 
65 
from esys.escript import * 
66 
import esys.finley 
67 
from esys.escript.linearPDEs import LinearPDE 
68 
from esys.escript.models import StokesProblemCartesian 
69 

70 
#physical constants 
71 
eta=1.0 
72 
rho=100.0 
73 
g=10.0 
74 

75 
#solver settings 
76 
tolerance=1.0e4 
77 
max_iter=200 
78 
t_end=50 
79 
t=0.0 
80 
time=0 
81 
verbose=True 
82 

83 
#define mesh 
84 
H=2.0 
85 
L=1.0 
86 
W=1.0 
87 
mesh = esys.finley.Rectangle(l0=L, l1=H, order=2, n0=20, n1=20) 
88 
coordinates = mesh.getX() 
89 

90 
#gravitational force 
91 
Y=Vector(0.0, Function(mesh)) 
92 
Y[1]=rho*g 
93 

94 
#element spacing 
95 
h=Lsup(mesh.getSize()) 
96 

97 
#boundary conditions for slip at base 
98 
boundary_cond=whereZero(coordinates[1])*[0.0,1.0] 
99 

100 
#velocity and pressure vectors 
101 
velocity=Vector(0.0, ContinuousFunction(mesh)) 
102 
pressure=Scalar(0.0, ContinuousFunction(mesh)) 
103 

104 
#Stokes Cartesian 
105 
solution=StokesProblemCartesian(mesh) 
106 
solution.setTolerance(tolerance) 
107 

108 
while t <= t_end: 
109 

110 
print "  Time step = %s "%( t ) 
111 
print "Time = %s seconds"%( time ) 
112 

113 
solution.initialize(fixed_u_mask=boundary_cond,eta=eta,f=Y) 
114 
velocity,pressure=solution.solve(velocity,pressure,max_iter=max_iter, \ 
115 
verbose=verbose) 
116 

117 
print "Max velocity =", Lsup(velocity), "m/s" 
118 

119 
#Courant condition 
120 
dt=0.4*h/(Lsup(velocity)) 
121 
print "dt", dt 
122 

123 
#displace the mesh 
124 
displacement = velocity * dt 
125 
coordinates = mesh.getX() 
126 
mesh.setX(coordinates + displacement) 
127 

128 
time += dt 
129 

130 
vel_mag = length(velocity) 
131 

132 
#save velocity and pressure output 
133 
saveVTK("vel.%2.2i.vtu"%(t),vel=vel_mag,vec=velocity,pressure=pressure) 
134 
t = t+1.0 
135 

136 
\end{python} 
137 
% 
138 
The results from the simulation can be viewed with \mayavi, by executing the following command: 
139 
% 
140 
\begin{python} 
141 
mayavi d vel.00.vtu m SurfaceMap 
142 
\end{python} 
143 
% 
144 
Colour coded scalar maps and velocity flow fields can be viewed by selecting them in the menu. The timesteps can be swept through to view a movie of the simulation. 
145 
Figures \ref{FLUID OUTPUT1} and \ref{FLUID OUTPUT2} shows the simulation output. Velocity vectors and a colour map for pressure are shown. As the time progresses the body of fluid falls under the influence of gravity. 
146 
% 
147 
\begin{figure}[ht] 
148 
\center 
149 
\subfigure[t=1]{\label{FLOW OUTPUT 01}\includegraphics[scale=0.25]{figures/stokesfluidt01}} 
150 
\subfigure[t=20]{\label{FLOW OUTPUT 10}\includegraphics[scale=0.25]{figures/stokesfluidt10}} 
151 
\subfigure[t=30]{\label{FLOW OUTPUT 20}\includegraphics[scale=0.25]{figures/stokesfluidt20}} 
152 
\includegraphics[scale=0.25]{figures/stokesfluidcolorbar} 
153 
\caption{Simulation output for Stokes flow. Fluid body starts off as a rectangular shape, then progresses downwards under the influence of gravity. Color coded distribution represents the scalar values for pressure. Velocity vectors are displayed at each node in the mesh to show the flow field. Computational mesh used was 20$\times$20 elements.} 
154 
\label{FLUID OUTPUT1} 
155 
\end{figure} 
156 
% 
157 
\begin{figure}[ht] 
158 
\center 
159 
\subfigure[t=40]{\label{FLOW OUTPUT 30}\includegraphics[scale=0.25]{figures/stokesfluidt30}} 
160 
\subfigure[t=50]{\label{FLOW OUTPUT 40}\includegraphics[scale=0.25]{figures/stokesfluidt40}} 
161 
\subfigure[t=60]{\label{FLOW OUTPUT 50}\includegraphics[scale=0.25]{figures/stokesfluidt50}} 
162 
\includegraphics[scale=0.25]{figures/stokesfluidcolorbar} 
163 
\caption{Simulation output for Stokes flow.} 
164 
\label{FLUID OUTPUT2} 
165 
\end{figure} 
166 
% 
167 
The view used here to track the fluid is the Lagrangian view, since the mesh moves with the fluid. One of the disadvantages of using the Lagrangian view is that the elements in the mesh become severely distorted after a period of time and introduce solver errors. To get around this limitation the Level Set Method can be used, with the Eulerian point of view for a fixed mesh. 
168 
%The Level Set Method is discussed in Section \ref{LEVELSET CHAP}. 