Skip to content

Commit 02cefdb

Browse files
committed
Added inc navier-stokes tutorial from paper
1 parent 616c2f0 commit 02cefdb

File tree

4 files changed

+180
-3
lines changed

4 files changed

+180
-3
lines changed
111 KB
Loading

deps/build.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ files = [
1212
"t0041_p_laplacian",
1313
"t004_hyperelasticity",
1414
"t005_dg_discretization",
15-
"t007_darcy"]
15+
"t007_darcy",
16+
"t008_inc_navier_stokes"]
1617

1718
Sys.rm(notebooks_dir;recursive=true,force=true)
1819
for file in files

docs/make.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ files = [
2828
"t0041_p_laplacian",
2929
"t004_hyperelasticity",
3030
"t005_dg_discretization",
31-
"t007_darcy"]
31+
"t007_darcy",
32+
"t008_inc_navier_stokes"]
3233

3334
for file in files
3435
file_jl = file*".jl"
@@ -44,7 +45,8 @@ pages = [
4445
"4 p-Laplacian" => "pages/t0041_p_laplacian.md",
4546
"5 Hyper-elasticity" => "pages/t004_hyperelasticity.md",
4647
"6 Poisson equation (with DG)" => "pages/t005_dg_discretization.md",
47-
"7 Darcy equation (with RT)" => "pages/t007_darcy.md"]
48+
"7 Darcy equation (with RT)" => "pages/t007_darcy.md",
49+
"8 Incompressible Navier-Stokes" => "pages/t008_inc_navier_stokes.md" ]
4850

4951
makedocs(
5052
sitename = "Gridap tutorials",

src/t008_inc_navier_stokes.jl

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# # Tutorial 8: Incompressible Navier-Stokes equations
2+
#
3+
#md # [![](https://mybinder.org/badge_logo.svg)](@__BINDER_ROOT_URL__/notebooks/t008_inc_navier_stokes.ipynb)
4+
#md # [![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](@__NBVIEWER_ROOT_URL__/notebooks/t008_inc_navier_stokes.ipynb)
5+
#
6+
# In this tutorial, we will learn
7+
# - How to solve nonlinear multi-field PDEs in Gridap
8+
# - How to build FE spaces whose functions have zero mean value
9+
#
10+
# ## Problem statement
11+
#
12+
# The goal of this last tutorial is to solve a nonlinear multi-field PDE. As a model problem, we consider a well known benchmark in computational fluid dynamics: the lid-driven cavity for the incompressible Navier-Stokes equations. Formally, the PDE we want to solve is: find the velocity vector $u$ and the pressure $p$ such that
13+
#
14+
# ```math
15+
# \left\lbrace
16+
# \begin{aligned}
17+
# -\Delta u + \mathit{Re}\ (u\cdot \nabla)\ u + \nabla p = 0 &\text{ in }\Omega,\\
18+
# \nabla\cdot u = 0 &\text{ in } \Omega,\\
19+
# u = g &\text{ on } \partial\Omega,
20+
# \end{aligned}
21+
# \right.
22+
# ```
23+
#
24+
# where the computational domain is the unit square $\Omega \doteq (0,1)^d$, $d=2$, $\mathit{Re}$ is the Reynolds number (here, we take $\mathit{Re}=10$), and $(w \cdot \nabla)\ u = (\nabla u)^t w$ is the well known convection operator. In this example, the driving force is the Dirichlet boundary velocity $g$, which is a non-zero horizontal velocity with a value of $g = (1,0)^t$ on the top side of the cavity, namely the boundary $(0,1)\times\{1\}$, and $g=0$ elsewhere on $\partial\Omega$. Since we impose Dirichlet boundary conditions on the entire boundary $\partial\Omega$, the mean value of the pressure is constrained to zero in order have a well posed problem,
25+
#
26+
# ```math
27+
# \int_\Omega q \ {\rm d}\Omega = 0.
28+
# ```
29+
#
30+
# ## Numerical Scheme
31+
#
32+
# In order to approximate this problem we chose a formulation based on inf-sub stable $Q_k/P_{k-1}$ elements with continuous velocities and discontinuous pressures (see, e.g., [1] for specific details). The interpolation spaces are defined as follows. The velocity interpolation space is
33+
#
34+
# ```math
35+
# V \doteq \{ v \in [C^0(\Omega)]^d:\ v|_T\in [Q_k(T)]^d \text{ for all } T\in\mathcal{T} \},
36+
# ```
37+
# where $T$ denotes an arbitrary cell of the FE mesh $\mathcal{T}$, and $Q_k(T)$ is the local polynomial space in cell $T$ defined as the multi-variate polynomials in $T$ of order less or equal to $k$ in each spatial coordinate. Note that, this is the usual continuous vector-valued Lagrangian FE space of order $k$ defined on a mesh of quadrilaterals or hexahedra. On the other hand, the space for the pressure~is
38+
#
39+
# ```math
40+
# \begin{aligned}
41+
# Q_0 &\doteq \{ q \in Q: \ \int_\Omega q \ {\rm d}\Omega = 0\}, \text{ with}\\
42+
# Q &\doteq \{ q \in L^2(\Omega):\ q|_T\in P_{k-1}(T) \text{ for all } T\in\mathcal{T}\},
43+
# \end{aligned}
44+
# ```
45+
# where $P_{k-1}(T)$ is the polynomial space of multi-variate polynomials in $T$ of degree less or equal to $k-1$. Note that functions in $Q_0$ are strongly constrained to have zero mean value. This is achieved in the code by removing one degree of freedom from the (unconstrained) interpolation space $Q$ and adding a constant to the computed pressure so that the resulting function has zero mean value.
46+
#
47+
# The weak form associated to these interpolation spaces reads: find $(u,p)\in U_g \times Q_0$ such that $[r(u,p)](v,q)=0$ for all $(v,q)\in V_0 \times Q_0$
48+
# where $U_g$ and $V_0$ are the set of functions in $V$ fulfilling the Dirichlet boundary condition $g$ and $0$ on $\partial\Omega$ respectively. The weak residual $r$ evaluated at a given pair $(u,p)$ is the linear form defined as
49+
#
50+
# ```math
51+
# [r(u,p)](v,q) \doteq a((v,q),(u,p))+ [c(u)](v),
52+
# ```
53+
# with
54+
# ```math
55+
# \begin{aligned}
56+
# a((v,q),(u,p)) &\doteq \int_{\Omega} \nabla v \cdot \nabla u \ {\rm d}\Omega - \int_{\Omega} (\nabla\cdot v) \ p \ {\rm d}\Omega + \int_{\Omega} q \ (\nabla \cdot u) \ {\rm d}\Omega,\\
57+
# [c(u)](v) &\doteq \int_{\Omega} v \cdot \left( (u\cdot\nabla)\ u \right)\ {\rm d}\Omega.\\
58+
# \end{aligned}
59+
# ```
60+
# Note that the bilinear form $a$ is associated with the linear part of the PDE, whereas $c$ is the contribution to the residual resulting from the convective term.
61+
#
62+
# In order to solve this nonlinear weak equation with a Newton-Raphson method, one needs to compute the Jacobian associated with the residual $r$. In this case, the Jacobian $j$ evaluated at a pair $(u,p)$ is the bilinear form defined as
63+
#
64+
# ```math
65+
# [j(u,p)]((v,q),(\delta u, \delta p)) \doteq a((v,q),(\delta u,\delta p)) + [{\rm d}c(u)](v,\delta u),
66+
# ```
67+
# where ${\rm d}c$ results from the linearization of the convective term, namely
68+
# ```math
69+
# [{\rm d}c(u)](v,\delta u) \doteq \int_{\Omega} v \cdot \left( (u\cdot\nabla)\ \delta u \right) \ {\rm d}\Omega + \int_{\Omega} v \cdot \left( (\delta u\cdot\nabla)\ u \right) \ {\rm d}\Omega.
70+
# ```
71+
# The implementation of this numerical scheme is done in Gridap by combining the concepts previously seen for single-field nonlinear PDEs and linear multi-field problems.
72+
#
73+
# ## Discrete model
74+
#
75+
# We start with the discretization of the computational domain. We consider a $100\times100$ Cartesian mesh of the unit square.
76+
77+
using Gridap
78+
n = 100
79+
model = CartesianDiscreteModel(domain=(0.0,1.0,0.0,1.0), partition=(n,n))
80+
81+
# For convenience, we create two new boundary tags, namely `"diri1"` and `"diri0"`, one for the top side of the square (where the velocity is non-zero), and another for the rest of the boundary (where the velocity is zero).
82+
83+
labels = FaceLabels(model)
84+
add_tag_from_tags!(labels,"diri1",[6,])
85+
add_tag_from_tags!(labels,"diri0",[1,2,3,4,5,7,8])
86+
87+
# ## FE spaces
88+
#
89+
# For the velocities, we need to create a conventional vector-valued continuous Lagrangian FE space. In this example, we select a second order interpolation.
90+
91+
D = 2
92+
order = 2
93+
fespace1 = FESpace(
94+
reffe=:Lagrangian, conformity=:H1, valuetype=VectorValue{D,Float64},
95+
model=model, labels=labels, order=order, diritags=["diri0","diri1"])
96+
97+
# The interpolation space for the pressure is build as follows
98+
99+
fespace2 = FESpace(
100+
reffe=:PLagrangian, conformity=:L2, valuetype=Float64,
101+
model=model, order=order-1, constraint=:zeromean)
102+
103+
# With the options `reffe=:PLagrangian`, `valuetype=Float64`, and `order=order-1`, we select the local polynomial space $P_{k-1}(T)$ on the cells $T\in\mathcal{T}$. With the symbol `:PLagrangian` we specifically chose a local Lagrangian interpolation of type "P". Using `:Lagrangian`, would lead to a local Lagrangian of type "Q" since this is the default for quadrilateral or hexahedral elements. On the other hand, `constraint=:zeromean` leads to a FE space, whose functions are constrained to have mean value equal to zero, which is just what we need for the pressure space. With these objects, we build the test and trial multi-field FE spaces
104+
105+
uD0(x) = VectorValue(0.0,0.0)
106+
uD1(x) = VectorValue(1.0,0.0)
107+
108+
V = TestFESpace(fespace1)
109+
Q = TestFESpace(fespace2)
110+
Y = [V, Q]
111+
112+
U = TrialFESpace(fespace1,[uD0,uD1])
113+
P = TrialFESpace(fespace2)
114+
X = [U, P]
115+
116+
# ## Nonlinear weak form
117+
#
118+
# The different terms of the nonlinear weak form for this example are defined following an approach similar to the one discussed for the $p$-Laplacian equation, but this time using the notation for multi-field problems.
119+
120+
const Re = 10.0
121+
@law conv(x,u,∇u) = Re*(∇u')*u
122+
@law dconv(x,du,∇du,u,∇u) = conv(x,u,∇du)+conv(x,du,∇u)
123+
124+
function a(y,x)
125+
u, p = x
126+
v, q = y
127+
inner((v),(u)) - inner(div(v),p) + inner(q,div(u))
128+
end
129+
130+
c(v,u) = inner(v,conv(u,(u)))
131+
dc(v,du,u) = inner(v,dconv(du,(du),u,(u)))
132+
133+
function res(x,y)
134+
u, p = x
135+
v, q = y
136+
a(y,x) + c(v,u)
137+
end
138+
139+
function jac(x,y,dx)
140+
u, p = x
141+
v, q = y
142+
du, dp = dx
143+
a(y,dx)+ dc(v,du,u)
144+
end
145+
146+
# With the functions `res`, and `jac` representing the weak residual and the Jacobian, we build the nonlinear FE problem:
147+
148+
trian = Triangulation(model)
149+
quad = CellQuadrature(trian,degree=(order-1)*2)
150+
t_Ω = NonLinearFETerm(res,jac,trian,quad)
151+
op = NonLinearFEOperator(Y,X,t_Ω)
152+
153+
# ## Nonlinear solver phase
154+
#
155+
# To finally solve the problem, we consider the same nonlinear solver as previously considered for the $p$-Laplacian equation.
156+
157+
using LineSearches: BackTracking
158+
nls = NLSolver(
159+
show_trace=true, method=:newton, linesearch=BackTracking())
160+
solver = NonLinearFESolver(nls)
161+
162+
# In this example, we solve the problem without providing an initial guess (a default one equal to zero will be generated internally)
163+
164+
uh, ph = solve(solver,op)
165+
166+
# Finally, we write the results for visualization (see next figure).
167+
168+
writevtk(trian,"ins-results",cellfields=["uh"=>uh,"ph"=>ph])
169+
170+
# ![](../assets/t008_inc_navier_stokes/ins_solution.png)
171+
#
172+
# ## References
173+
#
174+
# [1] H. C. Elman, D. J. Silvester, and A. J. Wathen. *Finite elements and fast iterative solvers: with applications in incompressible fluid dynamics*. Oxford University Press, 2005.

0 commit comments

Comments
 (0)