Toggle navigation
Documentation
Big picture
The finite element method
The data structure
Not-so-quick guide
Optimisation
Order of action functions
Example codes and tutorials
List of example codes and tutorials
Meshing
Solvers
MPI parallel processing
Post-processing/visualisation
Other
Change log
Creating documentation
Coding conventions
Index
FAQ
About
People
Contact/Get involved
Publications
Acknowledgements
Copyright
Picture show
Go
demo_drivers
navier_stokes
adaptive_driven_cavity
adaptive_driven_cavity.cc
Go to the documentation of this file.
1
//LIC// ====================================================================
2
//LIC// This file forms part of oomph-lib, the object-oriented,
3
//LIC// multi-physics finite-element library, available
4
//LIC// at http://www.oomph-lib.org.
5
//LIC//
6
//LIC// Copyright (C) 2006-2025 Matthias Heil and Andrew Hazel
7
//LIC//
8
//LIC// This library is free software; you can redistribute it and/or
9
//LIC// modify it under the terms of the GNU Lesser General Public
10
//LIC// License as published by the Free Software Foundation; either
11
//LIC// version 2.1 of the License, or (at your option) any later version.
12
//LIC//
13
//LIC// This library is distributed in the hope that it will be useful,
14
//LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
//LIC// Lesser General Public License for more details.
17
//LIC//
18
//LIC// You should have received a copy of the GNU Lesser General Public
19
//LIC// License along with this library; if not, write to the Free Software
20
//LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21
//LIC// 02110-1301 USA.
22
//LIC//
23
//LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24
//LIC//
25
//LIC//====================================================================
26
// Driver for adaptive 2D rectangular driven cavity. Solved with black
27
// box adaptation, using Taylor Hood and Crouzeix Raviart elements.
28
29
// Generic oomph-lib header
30
#include "generic.h"
31
32
// Navier Stokes headers
33
#include "navier_stokes.h"
34
35
// The mesh
36
#include "meshes/rectangular_quadmesh.h"
37
38
using namespace
std;
39
40
using namespace
oomph;
41
42
//==start_of_namespace===================================================
43
/// Namespace for physical parameters
44
//=======================================================================
45
namespace
Global_Physical_Variables
46
{
47
/// Reynolds number
48
double
Re
=100;
49
}
// end_of_namespace
50
51
52
53
//==start_of_problem_class============================================
54
/// Driven cavity problem in rectangular domain, templated
55
/// by element type.
56
//====================================================================
57
template
<
class
ELEMENT>
58
class
RefineableDrivenCavityProblem
:
public
Problem
59
{
60
61
public
:
62
63
/// Constructor
64
RefineableDrivenCavityProblem
();
65
66
/// Destructor: Empty
67
~RefineableDrivenCavityProblem
() {}
68
69
/// Update the after solve (empty)
70
void
actions_after_newton_solve
() {}
71
72
/// Update the problem specs before solve.
73
/// (Re-)set velocity boundary conditions just to be on the safe side...
74
void
actions_before_newton_solve
()
75
{
76
// Setup tangential flow along boundary 0:
77
unsigned
ibound=0;
78
unsigned
num_nod= mesh_pt()->nboundary_node(ibound);
79
for
(
unsigned
inod=0;inod<num_nod;inod++)
80
{
81
// Tangential flow
82
unsigned
i=0;
83
mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,1.0);
84
// No penetration
85
i=1;
86
mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,0.0);
87
}
88
89
// Overwrite with no flow along all other boundaries
90
unsigned
num_bound = mesh_pt()->nboundary();
91
for
(
unsigned
ibound=1;ibound<num_bound;ibound++)
92
{
93
unsigned
num_nod= mesh_pt()->nboundary_node(ibound);
94
for
(
unsigned
inod=0;inod<num_nod;inod++)
95
{
96
for
(
unsigned
i=0;i<2;i++)
97
{
98
mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,0.0);
99
}
100
}
101
}
102
}
// end_of_actions_before_newton_solve
103
104
105
/// After adaptation: Unpin pressure and pin redudant pressure dofs.
106
void
actions_after_adapt
()
107
{
108
// Unpin all pressure dofs
109
RefineableNavierStokesEquations<2>::
110
unpin_all_pressure_dofs(mesh_pt()->element_pt());
111
112
// Pin redundant pressure dofs
113
RefineableNavierStokesEquations<2>::
114
pin_redundant_nodal_pressures(mesh_pt()->element_pt());
115
116
// Now set the first pressure dof in the first element to 0.0
117
fix_pressure
(0,0,0.0);
118
}
// end_of_actions_after_adapt
119
120
/// Doc the solution
121
void
doc_solution
(DocInfo& doc_info);
122
123
124
private
:
125
126
/// Fix pressure in element e at pressure dof pdof and set to pvalue
127
void
fix_pressure
(
const
unsigned
&e,
const
unsigned
&pdof,
128
const
double
&pvalue)
129
{
130
//Cast to proper element and fix pressure
131
dynamic_cast<
ELEMENT*
>
(mesh_pt()->element_pt(e))->
132
fix_pressure
(pdof,pvalue);
133
}
// end_of_fix_pressure
134
135
};
// end_of_problem_class
136
137
138
139
//==start_of_constructor==================================================
140
/// Constructor for RefineableDrivenCavity problem
141
///
142
//========================================================================
143
template
<
class
ELEMENT>
144
RefineableDrivenCavityProblem<ELEMENT>::RefineableDrivenCavityProblem
()
145
{
146
147
// Setup mesh
148
149
// # of elements in x-direction
150
unsigned
n_x=10;
151
152
// # of elements in y-direction
153
unsigned
n_y=10;
154
155
// Domain length in x-direction
156
double
l_x=1.0;
157
158
// Domain length in y-direction
159
double
l_y=1.0;
160
161
// Build and assign mesh
162
Problem::mesh_pt() =
163
new
RefineableRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
164
165
// Set error estimator
166
Z2ErrorEstimator* error_estimator_pt=
new
Z2ErrorEstimator;
167
dynamic_cast<
RefineableRectangularQuadMesh<ELEMENT>*
>
(mesh_pt())->
168
spatial_error_estimator_pt()=error_estimator_pt;
169
170
// Set the boundary conditions for this problem: All nodes are
171
// free by default -- just pin the ones that have Dirichlet conditions
172
// here: All boundaries are Dirichlet boundaries.
173
unsigned
num_bound = mesh_pt()->nboundary();
174
for
(
unsigned
ibound=0;ibound<num_bound;ibound++)
175
{
176
unsigned
num_nod= mesh_pt()->nboundary_node(ibound);
177
for
(
unsigned
inod=0;inod<num_nod;inod++)
178
{
179
// Loop over values (u and v velocities)
180
for
(
unsigned
i=0;i<2;i++)
181
{
182
mesh_pt()->boundary_node_pt(ibound,inod)->pin(i);
183
}
184
}
185
}
// end loop over boundaries
186
187
//Find number of elements in mesh
188
unsigned
n_element = mesh_pt()->nelement();
189
190
// Loop over the elements to set up element-specific
191
// things that cannot be handled by constructor: Pass pointer to Reynolds
192
// number
193
for
(
unsigned
e=0;e<n_element;e++)
194
{
195
// Upcast from GeneralisedElement to the present element
196
ELEMENT* el_pt =
dynamic_cast<
ELEMENT*
>
(mesh_pt()->element_pt(e));
197
//Set the Reynolds number, etc
198
el_pt->re_pt() = &
Global_Physical_Variables::Re
;
199
}
// end loop over elements
200
201
// Pin redudant pressure dofs
202
RefineableNavierStokesEquations<2>::
203
pin_redundant_nodal_pressures(mesh_pt()->element_pt());
204
205
// Now set the first pressure dof in the first element to 0.0
206
fix_pressure(0,0,0.0);
207
208
// Setup equation numbering scheme
209
cout <<
"Number of equations: "
<< assign_eqn_numbers() << std::endl;
210
211
}
// end_of_constructor
212
213
214
215
//==start_of_doc_solution=================================================
216
/// Doc the solution
217
//========================================================================
218
template
<
class
ELEMENT>
219
void
RefineableDrivenCavityProblem<ELEMENT>::doc_solution
(DocInfo& doc_info)
220
{
221
222
ofstream some_file;
223
char
filename[100];
224
225
// Number of plot points
226
unsigned
npts=5;
227
228
229
// Output solution
230
snprintf(filename,
sizeof
(filename),
"%s/soln%i.dat"
,doc_info.directory().c_str(),
231
doc_info.number());
232
some_file.open(filename);
233
mesh_pt()->output(some_file,npts);
234
some_file.close();
235
236
}
// end_of_doc_solution
237
238
239
240
241
//==start_of_main======================================================
242
/// Driver for RefineableDrivenCavity test problem
243
//=====================================================================
244
int
main
()
245
{
246
247
// Set output directory
248
DocInfo doc_info;
249
doc_info.set_directory(
"RESLT"
);
250
251
252
// Set max. number of black-box adaptation
253
unsigned
max_adapt=3;
254
255
// Solve problem with Taylor Hood elements
256
//---------------------------------------
257
{
258
//Build problem
259
RefineableDrivenCavityProblem<RefineableQTaylorHoodElement<2>
> problem;
260
261
// Solve the problem with automatic adaptation
262
problem.newton_solve(max_adapt);
263
264
// Step number
265
doc_info.number()=0;
266
267
//Output solution
268
problem.
doc_solution
(doc_info);
269
}
// end of Taylor Hood elements
270
271
272
// Solve problem with Crouzeix Raviart elements
273
//--------------------------------------------
274
{
275
// Build problem
276
RefineableDrivenCavityProblem<RefineableQCrouzeixRaviartElement<2>
> problem;
277
278
// Solve the problem with automatic adaptation
279
problem.newton_solve(max_adapt);
280
281
// Step number
282
doc_info.number()=1;
283
284
//Output solution
285
problem.
doc_solution
(doc_info);
286
}
// end of Crouzeix Raviart elements
287
288
289
}
// end_of_main
290
291
292
293
294
295
296
297
298
299
300
main
int main()
Driver for RefineableDrivenCavity test problem.
Definition
adaptive_driven_cavity.cc:244
RefineableDrivenCavityProblem
Driven cavity problem in rectangular domain, templated by element type.
Definition
adaptive_driven_cavity.cc:59
RefineableDrivenCavityProblem::doc_solution
void doc_solution(DocInfo &doc_info)
Doc the solution.
Definition
adaptive_driven_cavity.cc:219
RefineableDrivenCavityProblem::actions_after_newton_solve
void actions_after_newton_solve()
Update the after solve (empty)
Definition
adaptive_driven_cavity.cc:70
RefineableDrivenCavityProblem::~RefineableDrivenCavityProblem
~RefineableDrivenCavityProblem()
Destructor: Empty.
Definition
adaptive_driven_cavity.cc:67
RefineableDrivenCavityProblem::actions_after_adapt
void actions_after_adapt()
After adaptation: Unpin pressure and pin redudant pressure dofs.
Definition
adaptive_driven_cavity.cc:106
RefineableDrivenCavityProblem::fix_pressure
void fix_pressure(const unsigned &e, const unsigned &pdof, const double &pvalue)
Fix pressure in element e at pressure dof pdof and set to pvalue.
Definition
adaptive_driven_cavity.cc:127
RefineableDrivenCavityProblem::RefineableDrivenCavityProblem
RefineableDrivenCavityProblem()
Constructor.
Definition
adaptive_driven_cavity.cc:144
RefineableDrivenCavityProblem::actions_before_newton_solve
void actions_before_newton_solve()
Update the problem specs before solve. (Re-)set velocity boundary conditions just to be on the safe s...
Definition
adaptive_driven_cavity.cc:74
Global_Physical_Variables
Namespace for physical parameters.
Definition
adaptive_driven_cavity.cc:46
Global_Physical_Variables::Re
double Re
Reynolds number.
Definition
adaptive_driven_cavity.cc:48