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
meshing
mesh_from_tetgen
mesh_from_tetgen_poisson.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 function for a simple test poisson problem using a mesh
27
// generated from an input file generated by the tetrahedra mesh generator.
28
// the files .node, .ele and .face should be specified in this order
29
30
//Generic routines
31
#include "generic.h"
32
33
// Poisson equations
34
#include "poisson.h"
35
36
// Get the mesh
37
#include "
meshes/tetgen_mesh.h
"
38
39
using namespace
std;
40
41
using namespace
oomph
;
42
43
//=============start_of_namespace=====================================
44
/// Namespace for exact solution for Poisson equation with sharp step
45
//====================================================================
46
namespace
TanhSolnForPoisson
47
{
48
49
/// Parameter for steepness of step
50
double
Alpha
=3;
51
52
/// Orientation (non-normalised x-component of unit vector in direction
53
/// of step plane)
54
double
N_x
=-1.0;
55
56
/// Orientation (non-normalised y-component of unit vector in direction
57
/// of step plane)
58
double
N_y
=-1.0;
59
60
/// Orientation (non-normalised z-component of unit vector in direction
61
/// of step plane)
62
double
N_z
=1.0;
63
64
65
/// Orientation (x-coordinate of step plane)
66
double
X_0
=0.0;
67
68
/// Orientation (y-coordinate of step plane)
69
double
Y_0
=0.0;
70
71
/// Orientation (z-coordinate of step plane)
72
double
Z_0
=0.0;
73
74
75
// Exact solution as a Vector
76
void
get_exact_u
(
const
Vector<double>
& x,
Vector<double>
&
u
)
77
{
78
u
[0] =
tanh
(
Alpha
*((x[0]-
X_0
)*
N_x
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[1]-
Y_0
)*
79
N_y
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
80
N_z
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)));
81
}
82
83
/// Exact solution as a scalar
84
void
get_exact_u
(
const
Vector<double>
& x,
double
&
u
)
85
{
86
u
=
tanh
(
Alpha
*((x[0]-
X_0
)*
N_x
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[1]-
Y_0
)*
87
N_y
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
88
N_z
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)));
89
}
90
91
92
/// Source function to make it an exact solution
93
void
get_source
(
const
Vector<double>
& x,
double
&
source
)
94
{
95
96
double
s1
,
s2
,
s3
,
s4
;
97
98
s1
= -2.0*
tanh
(
Alpha
*((x[0]-
X_0
)*
N_x
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[1]-
99
Y_0
)*
N_y
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
N_z
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
100
N_z
)))*(1.0-
pow
(
tanh
(
Alpha
*((x[0]-
X_0
)*
N_x
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[1]-
101
Y_0
)*
N_y
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
N_z
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
102
N_z
))),2.0))*
Alpha
*
Alpha
*
N_x
*
N_x
/(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
);
103
s3
= -2.0*
tanh
(
Alpha
*((x[0]-
X_0
)*
N_x
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[1]-
104
Y_0
)*
N_y
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
N_z
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
105
N_z
)))*(1.0-
pow
(
tanh
(
Alpha
*((x[0]-
X_0
)*
N_x
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[1]-
106
Y_0
)*
N_y
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
N_z
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
107
N_z
))),2.0))*
Alpha
*
Alpha
*
N_y
*
N_y
/(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
);
108
s4
= -2.0*
tanh
(
Alpha
*((x[0]-
X_0
)*
N_x
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[1]-
109
Y_0
)*
N_y
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
N_z
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
110
N_z
)))*(1.0-
pow
(
tanh
(
Alpha
*((x[0]-
X_0
)*
N_x
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[1]-
111
Y_0
)*
N_y
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
N_z
/
sqrt
(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
112
N_z
))),2.0))*
Alpha
*
Alpha
*
N_z
*
N_z
/(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
);
113
s2
=
s3
+
s4
;
114
source
=
s1
+
s2
;
115
}
116
117
118
}
// end of namespace
119
120
121
122
123
124
//====================================================================
125
/// Micky mouse Poisson problem.
126
//====================================================================
127
template
<
class
ELEMENT>
128
class
PoissonProblem
:
public
Problem
129
{
130
131
public
:
132
133
134
/// Constructor
135
PoissonProblem
(
PoissonEquations<3>::PoissonSourceFctPt
source_fct_pt
,
136
const
string
&
node_file_name
,
137
const
string
&
element_file_name
,
138
const
string
&
face_file_name
);
139
140
/// Destructor (empty)
141
~PoissonProblem
(){}
142
143
144
/// Update the problem specs before solve: (Re)set boundary conditions
145
void
actions_before_newton_solve
()
146
{
147
//Loop over the boundaries
148
unsigned
num_bound
=
mesh_pt
()->nboundary();
149
for
(
unsigned
ibound
=0;
ibound
<
num_bound
;
ibound
++)
150
{
151
// Loop over the nodes on boundary
152
unsigned
num_nod
=
mesh_pt
()->nboundary_node(
ibound
);
153
for
(
unsigned
inod
=0;
inod
<
num_nod
;
inod
++)
154
{
155
Node
*
nod_pt
=
mesh_pt
()->boundary_node_pt(
ibound
,
inod
);
156
double
u
;
157
Vector<double>
x(3);
158
x[0]=
nod_pt
->x(0);
159
x[1]=
nod_pt
->x(1);
160
x[2]=
nod_pt
->x(2);
161
TanhSolnForPoisson::get_exact_u
(x,
u
);
162
nod_pt
->set_value(0,
u
);
163
}
164
}
165
}
166
167
/// Update the problem specs before solve (empty)
168
void
actions_after_newton_solve
(){}
169
170
171
//Access function for the specific mesh
172
TetgenMesh<ELEMENT>
*
mesh_pt
()
173
{
174
return
dynamic_cast<
TetgenMesh<ELEMENT>
*
>
(Problem::mesh_pt());
175
}
176
177
/// Doc the solution
178
void
doc_solution
(
const
unsigned
&
nplot
,
DocInfo
&
doc_info
);
179
180
private
:
181
182
/// Pointer to source function
183
PoissonEquations<3>::PoissonSourceFctPt
Source_fct_pt
;
184
185
};
186
187
188
189
//========================================================================
190
/// Constructor for Poisson problem
191
//========================================================================
192
template
<
class
ELEMENT>
193
PoissonProblem<ELEMENT>::
194
PoissonProblem
(
PoissonEquations<3>::PoissonSourceFctPt
source_fct_pt
,
195
const
string
&
node_file_name
,
196
const
string
&
element_file_name
,
197
const
string
&
face_file_name
)
198
: Source_fct_pt(
source_fct_pt
)
199
{
200
201
// Setup parameters for exact tanh solution
202
203
// Steepness of step
204
TanhSolnForPoisson::Alpha
=1.0;
205
206
207
//Create mesh
208
Problem::mesh_pt() =
new
TetgenMesh<ELEMENT>
(
node_file_name
,
209
element_file_name
,
210
face_file_name
);
211
212
// Set the boundary conditions for this problem: All nodes are
213
// free by default -- just pin the ones that have Dirichlet conditions
214
// here.
215
unsigned
num_bound
=
mesh_pt
()->nboundary();
216
for
(
unsigned
ibound
=0;
ibound
<
num_bound
;
ibound
++)
217
{
218
unsigned
num_nod
=
mesh_pt
()->nboundary_node(
ibound
);
219
for
(
unsigned
inod
=0;
inod
<
num_nod
;
inod
++)
220
{
221
mesh_pt
()->boundary_node_pt(
ibound
,
inod
)->pin(0);
222
}
223
}
224
225
// Complete the build of all elements so they are fully functional
226
227
//Find number of elements in mesh
228
unsigned
n_element
=
mesh_pt
()->nelement();
229
230
// Loop over the elements to set up element-specific
231
// things that cannot be handled by constructor
232
for
(
unsigned
i
=0;
i
<
n_element
;
i
++)
233
{
234
// Upcast from GeneralElement to the present element
235
ELEMENT
*
el_pt
=
dynamic_cast<
ELEMENT
*
>
(
mesh_pt
()->element_pt(
i
));
236
237
//Set the source function pointer
238
el_pt
->source_fct_pt() =
Source_fct_pt
;
239
}
240
241
// Setup equation numbering scheme
242
cout
<<
"Number of equations: "
<<
assign_eqn_numbers
() << std::endl;
243
244
}
245
246
247
248
//========================================================================
249
/// Doc the solution
250
//========================================================================
251
template
<
class
ELEMENT>
252
void
PoissonProblem<ELEMENT>::doc_solution
(
const
unsigned
&
nplot
,
253
DocInfo
&
doc_info
)
254
{
255
256
ofstream
some_file
;
257
char
filename
[100];
258
259
260
// Doc local node numbering
261
//-------------------------
262
snprintf
(
filename
,
sizeof
(
filename
),
"%s/node_numbering%i.dat"
,
doc_info
.directory().c_str(),
263
doc_info
.number());
264
some_file
.open(
filename
);
265
FiniteElement
*
el_pt
=mesh_pt()->finite_element_pt(0);
266
unsigned
nnode
=
el_pt
->nnode();
267
unsigned
ndim
=
el_pt
->node_pt(0)->ndim();
268
for
(
unsigned
j
=0;
j
<
nnode
;
j
++)
269
{
270
for
(
unsigned
i
=0;
i
<
ndim
;
i
++)
271
{
272
some_file
<<
el_pt
->node_pt(
j
)->x(
i
) <<
" "
;
273
}
274
some_file
<<
j
<< std::endl;
275
}
276
some_file
.close();
277
278
// Output boundaries
279
//------------------
280
snprintf
(
filename
,
sizeof
(
filename
),
"%s/boundaries%i.dat"
,
doc_info
.directory().c_str(),
281
doc_info
.number());
282
some_file
.open(
filename
);
283
mesh_pt()->output_boundaries(
some_file
);
284
some_file
.close();
285
286
287
// Output solution
288
//----------------
289
snprintf
(
filename
,
sizeof
(
filename
),
"%s/soln%i.dat"
,
doc_info
.directory().c_str(),
290
doc_info
.number());
291
some_file
.open(
filename
);
292
mesh_pt()->output(
some_file
,
nplot
);
293
some_file
.close();
294
295
296
// Output exact solution
297
//----------------------
298
snprintf
(
filename
,
sizeof
(
filename
),
"%s/exact_soln%i.dat"
,
doc_info
.directory().c_str(),
299
doc_info
.number());
300
some_file
.open(
filename
);
301
mesh_pt()->output_fct(
some_file
,
nplot
,
TanhSolnForPoisson::get_exact_u
);
302
some_file
.close();
303
304
// Doc error
305
//----------
306
double
error
,
norm
;
307
snprintf
(
filename
,
sizeof
(
filename
),
"%s/error%i.dat"
,
doc_info
.directory().c_str(),
308
doc_info
.number());
309
some_file
.open(
filename
);
310
mesh_pt()->compute_error(
some_file
,
TanhSolnForPoisson::get_exact_u
,
311
error
,
norm
);
312
some_file
.close();
313
cout
<<
"error: "
<<
sqrt
(
error
) << std::endl;
314
cout
<<
"norm : "
<<
sqrt
(
norm
) << std::endl << std::endl;
315
316
}
// end of doc
317
318
319
320
321
//========================================================================
322
/// Demonstrate how to solve Poisson problem
323
//========================================================================
324
int
main
(
int
argc
,
char
*
argv
[])
325
{
326
327
// Store command line arguments
328
CommandLineArgs::setup(
argc
,
argv
);
329
330
// Check number of command line arguments: Need exactly three.
331
if
(
argc
!=4)
332
{
333
std::string
error_message
=
334
"Wrong number of command line arguments.\n"
;
335
error_message
+=
336
"Must specify the following file names \n"
;
337
error_message
+=
338
"filename.node then filename.ele then filename.face\n"
;
339
340
throw
OomphLibError
(
error_message
,
341
OOMPH_CURRENT_FUNCTION
,
342
OOMPH_EXCEPTION_LOCATION
);
343
}
344
345
// Convert arguments to strings that specify the input file names
346
string
node_file_name
(
argv
[1]);
347
string
element_file_name
(
argv
[2]);
348
string
face_file_name
(
argv
[3]);
349
350
351
// Label for output
352
DocInfo
doc_info
;
353
354
// Output directory
355
doc_info
.set_directory(
"RESLT"
);
356
357
// Number of output points per edge
358
unsigned
nplot
=2;
359
360
// Do the problem with linear elements
361
//------------------------------------
362
{
363
PoissonProblem<TPoissonElement<3,2>
>
364
problem
(&
TanhSolnForPoisson::get_source
,
365
node_file_name
,
element_file_name
,
face_file_name
);
366
367
// Solve the problem
368
problem
.newton_solve();
369
370
//Output solution with 2 points per edge
371
nplot
=2;
372
problem
.doc_solution(
nplot
,
doc_info
);
373
374
//Increment counter for solutions
375
doc_info
.number()++;
376
377
//Output solution with 5 points per edge
378
nplot
=5;
379
problem
.doc_solution(
nplot
,
doc_info
);
380
381
//Increment counter for solutions
382
doc_info
.number()++;
383
384
385
}
386
387
388
389
// Do the problem with quadratic elements
390
//---------------------------------------
391
{
392
PoissonProblem<TPoissonElement<3,3>
>
393
problem
(&
TanhSolnForPoisson::get_source
,
394
node_file_name
,
element_file_name
,
face_file_name
);
395
396
// Solve the problem
397
problem
.newton_solve();
398
399
//Output solution with 2 points per edge
400
nplot
=2;
401
problem
.doc_solution(
nplot
,
doc_info
);
402
403
//Increment counter for solutions
404
doc_info
.number()++;
405
406
//Output solution with 5 points per edge
407
nplot
=5;
408
problem
.doc_solution(
nplot
,
doc_info
);
409
410
//Increment counter for solutions
411
doc_info
.number()++;
412
413
}
414
415
416
}
417
418
419
PoissonProblem
Micky mouse Poisson problem.
Definition
mesh_from_tetgen_poisson.cc:129
PoissonProblem::actions_before_newton_solve
void actions_before_newton_solve()
Update the problem specs before solve: (Re)set boundary conditions.
Definition
mesh_from_tetgen_poisson.cc:145
PoissonProblem::mesh_pt
TetgenMesh< ELEMENT > * mesh_pt()
Definition
mesh_from_tetgen_poisson.cc:172
PoissonProblem::actions_after_newton_solve
void actions_after_newton_solve()
Update the problem specs before solve (empty)
Definition
mesh_from_tetgen_poisson.cc:168
PoissonProblem::doc_solution
void doc_solution(const unsigned &nplot, DocInfo &doc_info)
Doc the solution.
Definition
mesh_from_tetgen_poisson.cc:252
PoissonProblem::~PoissonProblem
~PoissonProblem()
Destructor (empty)
Definition
mesh_from_tetgen_poisson.cc:141
PoissonProblem::Source_fct_pt
PoissonEquations< 3 >::PoissonSourceFctPt Source_fct_pt
Pointer to source function.
Definition
mesh_from_tetgen_poisson.cc:183
PoissonProblem::PoissonProblem
PoissonProblem(PoissonEquations< 3 >::PoissonSourceFctPt source_fct_pt, const string &node_file_name, const string &element_file_name, const string &face_file_name)
Constructor.
Definition
mesh_from_tetgen_poisson.cc:194
oomph::TetgenMesh
Unstructured tet mesh based on output from Tetgen: http://wias-berlin.de/software/tetgen/.
Definition
tetgen_mesh.h:51
oomph::TetgenMesh::TetgenMesh
TetgenMesh()
Empty constructor.
Definition
tetgen_mesh.h:54
main
int main(int argc, char *argv[])
3D Navier Stokes on an unstructured mesh
Definition
mesh_from_tetgen_navier_stokes.cc:235
TanhSolnForPoisson
Namespace for exact solution for Poisson equation with sharp step.
Definition
mesh_from_tetgen_poisson.cc:47
TanhSolnForPoisson::N_y
double N_y
Orientation (non-normalised y-component of unit vector in direction of step plane)
Definition
mesh_from_tetgen_poisson.cc:58
TanhSolnForPoisson::Z_0
double Z_0
Orientation (z-coordinate of step plane)
Definition
mesh_from_tetgen_poisson.cc:72
TanhSolnForPoisson::N_x
double N_x
Orientation (non-normalised x-component of unit vector in direction of step plane)
Definition
mesh_from_tetgen_poisson.cc:54
TanhSolnForPoisson::Y_0
double Y_0
Orientation (y-coordinate of step plane)
Definition
mesh_from_tetgen_poisson.cc:69
TanhSolnForPoisson::get_source
void get_source(const Vector< double > &x, double &source)
Source function to make it an exact solution.
Definition
mesh_from_tetgen_poisson.cc:93
TanhSolnForPoisson::Alpha
double Alpha
Parameter for steepness of step.
Definition
mesh_from_tetgen_poisson.cc:50
TanhSolnForPoisson::N_z
double N_z
Orientation (non-normalised z-component of unit vector in direction of step plane)
Definition
mesh_from_tetgen_poisson.cc:62
TanhSolnForPoisson::X_0
double X_0
Orientation (x-coordinate of step plane)
Definition
mesh_from_tetgen_poisson.cc:66
TanhSolnForPoisson::get_exact_u
void get_exact_u(const Vector< double > &x, Vector< double > &u)
Definition
mesh_from_tetgen_poisson.cc:76
oomph
Definition
annular_domain.h:35
tetgen_mesh.h