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
poisson
eighth_sphere_poisson
eighth_sphere_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 for a 3D poisson problem
27
28
//Generic routines
29
#include "generic.h"
30
31
// The Poisson equations
32
#include "poisson.h"
33
34
// The mesh
35
#include "meshes/eighth_sphere_mesh.h"
36
37
using namespace
std;
38
39
using namespace
oomph;
40
41
//=============start_of_namespace=====================================
42
/// Namespace for exact solution for Poisson equation with sharp step
43
//====================================================================
44
namespace
TanhSolnForPoisson
45
{
46
47
/// Parameter for steepness of step
48
double
Alpha
=1;
49
50
/// Orientation (non-normalised x-component of unit vector in direction
51
/// of step plane)
52
double
N_x
=-1.0;
53
54
/// Orientation (non-normalised y-component of unit vector in direction
55
/// of step plane)
56
double
N_y
=-1.0;
57
58
/// Orientation (non-normalised z-component of unit vector in direction
59
/// of step plane)
60
double
N_z
=1.0;
61
62
63
/// Orientation (x-coordinate of step plane)
64
double
X_0
=0.0;
65
66
/// Orientation (y-coordinate of step plane)
67
double
Y_0
=0.0;
68
69
/// Orientation (z-coordinate of step plane)
70
double
Z_0
=0.0;
71
72
73
// Exact solution as a Vector
74
void
get_exact_u
(
const
Vector<double>& x, Vector<double>& u)
75
{
76
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
)*
77
N_y
/sqrt(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
78
N_z
/sqrt(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)));
79
}
80
81
/// Exact solution as a scalar
82
void
get_exact_u
(
const
Vector<double>& x,
double
& u)
83
{
84
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
)*
85
N_y
/sqrt(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)+(x[2]-
Z_0
)*
86
N_z
/sqrt(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
)));
87
}
88
89
90
/// Source function to make it an exact solution
91
void
get_source
(
const
Vector<double>& x,
double
& source)
92
{
93
94
double
s1,s2,s3,s4;
95
96
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]-
97
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
*
98
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]-
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
))),2.0))*
Alpha
*
Alpha
*
N_x
*
N_x
/(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
);
101
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]-
102
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
*
103
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]-
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
))),2.0))*
Alpha
*
Alpha
*
N_y
*
N_y
/(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
);
106
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]-
107
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
*
108
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]-
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
))),2.0))*
Alpha
*
Alpha
*
N_z
*
N_z
/(
N_x
*
N_x
+
N_y
*
N_y
+
N_z
*
N_z
);
111
s2 = s3+s4;
112
source = s1+s2;
113
}
114
115
116
}
// end of namespace
117
118
119
120
121
////////////////////////////////////////////////////////////////////////
122
////////////////////////////////////////////////////////////////////////
123
////////////////////////////////////////////////////////////////////////
124
125
126
127
//=======start_of_class_definition====================================
128
/// Poisson problem in refineable eighth of a sphere mesh.
129
//====================================================================
130
template
<
class
ELEMENT>
131
class
EighthSpherePoissonProblem
:
public
Problem
132
{
133
134
public
:
135
136
/// Constructor: Pass pointer to source function
137
EighthSpherePoissonProblem
(
138
PoissonEquations<3>::PoissonSourceFctPt source_fct_pt);
139
140
/// Destructor: Empty
141
~EighthSpherePoissonProblem
(){}
142
143
/// Overload generic access function by one that returns
144
/// a pointer to the specific mesh
145
RefineableEighthSphereMesh<ELEMENT>*
mesh_pt
()
146
{
147
return
dynamic_cast<
RefineableEighthSphereMesh<ELEMENT>*
>
(Problem::mesh_pt());
148
}
149
150
/// Update the problem specs after solve (empty)
151
void
actions_after_newton_solve
() {}
152
153
/// Update the problem specs before solve:
154
/// Set Dirchlet boundary conditions from exact solution.
155
void
actions_before_newton_solve
()
156
{
157
//Loop over the boundaries
158
unsigned
num_bound =
mesh_pt
()->nboundary();
159
for
(
unsigned
ibound=0;ibound<num_bound;ibound++)
160
{
161
// Loop over the nodes on boundary
162
unsigned
num_nod=
mesh_pt
()->nboundary_node(ibound);
163
for
(
unsigned
inod=0;inod<num_nod;inod++)
164
{
165
Node* nod_pt=
mesh_pt
()->boundary_node_pt(ibound,inod);
166
double
u;
167
Vector<double> x(3);
168
x[0]=nod_pt->x(0);
169
x[1]=nod_pt->x(1);
170
x[2]=nod_pt->x(2);
171
TanhSolnForPoisson::get_exact_u
(x,u);
172
nod_pt->set_value(0,u);
173
}
174
}
175
}
176
177
/// Doc the solution
178
void
doc_solution
(DocInfo& doc_info);
179
180
private
:
181
182
/// Pointer to source function
183
PoissonEquations<3>::PoissonSourceFctPt
Source_fct_pt
;
184
185
};
// end of class definition
186
187
188
189
190
191
//====================start_of_constructor================================
192
/// Constructor for Poisson problem on eighth of a sphere mesh
193
//========================================================================
194
template
<
class
ELEMENT>
195
EighthSpherePoissonProblem<ELEMENT>::EighthSpherePoissonProblem
(
196
PoissonEquations<3>::PoissonSourceFctPt source_fct_pt) :
197
Source_fct_pt(source_fct_pt)
198
{
199
200
// Setup parameters for exact tanh solution
201
// Steepness of step
202
TanhSolnForPoisson::Alpha
=50.0;
203
204
/// Create mesh for sphere of radius 5
205
double
radius=5.0;
206
Problem::mesh_pt() =
new
RefineableEighthSphereMesh<ELEMENT>(radius);
207
208
// Set error estimator
209
Z2ErrorEstimator* error_estimator_pt=
new
Z2ErrorEstimator;
210
mesh_pt
()->spatial_error_estimator_pt()=error_estimator_pt;
211
212
// Adjust error targets for adaptive refinement
213
if
(CommandLineArgs::Argc>1)
214
{
215
// Validation: Relax tolerance to get nonuniform refinement during
216
// first step
217
mesh_pt
()->max_permitted_error()=0.7;
218
mesh_pt
()->min_permitted_error()=0.5;
219
}
220
else
221
{
222
mesh_pt
()->max_permitted_error()=0.01;
223
mesh_pt
()->min_permitted_error()=0.001;
224
}
// end adjustment
225
226
//Doc the mesh boundaries
227
ofstream some_file;
228
some_file.open(
"boundaries.dat"
);
229
mesh_pt
()->output_boundaries(some_file);
230
some_file.close();
231
232
// Set the boundary conditions for this problem: All nodes are
233
// free by default -- just pin the ones that have Dirichlet conditions
234
// here (all the nodes on the boundary)
235
unsigned
num_bound =
mesh_pt
()->nboundary();
236
for
(
unsigned
ibound=0;ibound<num_bound;ibound++)
237
{
238
unsigned
num_nod=
mesh_pt
()->nboundary_node(ibound);
239
for
(
unsigned
inod=0;inod<num_nod;inod++)
240
{
241
mesh_pt
()->boundary_node_pt(ibound,inod)->pin(0);
242
}
243
}
// end of pinning
244
245
246
//Find number of elements in mesh
247
unsigned
n_element =
mesh_pt
()->nelement();
248
249
// Loop over the elements to set up element-specific
250
// things that cannot be handled by constructor
251
for
(
unsigned
i=0;i<n_element;i++)
252
{
253
// Upcast from FiniteElement to the present element
254
ELEMENT *el_pt =
dynamic_cast<
ELEMENT*
>
(
mesh_pt
()->element_pt(i));
255
256
//Set the source function pointer
257
el_pt->source_fct_pt() =
Source_fct_pt
;
258
}
259
260
// Setup equation numbering
261
cout <<
"Number of equations: "
<< assign_eqn_numbers() << std::endl;
262
263
}
// end of constructor
264
265
266
267
//========================start_of_doc====================================
268
/// Doc the solution
269
//========================================================================
270
template
<
class
ELEMENT>
271
void
EighthSpherePoissonProblem<ELEMENT>::doc_solution
(DocInfo& doc_info)
272
{
273
ofstream some_file;
274
char
filename[100];
275
276
// Number of plot points
277
unsigned
npts;
278
npts=5;
279
280
281
// Output solution
282
//-----------------
283
snprintf(filename,
sizeof
(filename),
"%s/soln%i.dat"
,doc_info.directory().c_str(),
284
doc_info.number());
285
some_file.open(filename);
286
mesh_pt()->output(some_file,npts);
287
some_file.close();
288
289
290
// Output exact solution
291
//----------------------
292
snprintf(filename,
sizeof
(filename),
"%s/exact_soln%i.dat"
,doc_info.directory().c_str(),
293
doc_info.number());
294
some_file.open(filename);
295
mesh_pt()->output_fct(some_file,npts,
TanhSolnForPoisson::get_exact_u
);
296
some_file.close();
297
298
299
// Doc error
300
//----------
301
double
error,norm;
302
snprintf(filename,
sizeof
(filename),
"%s/error%i.dat"
,doc_info.directory().c_str(),
303
doc_info.number());
304
some_file.open(filename);
305
mesh_pt()->compute_error(some_file,
TanhSolnForPoisson::get_exact_u
,
306
error,norm);
307
some_file.close();
308
cout <<
"error: "
<< sqrt(error) << std::endl;
309
cout <<
"norm : "
<< sqrt(norm) << std::endl << std::endl;
310
311
}
// end of doc
312
313
314
////////////////////////////////////////////////////////////////////////
315
////////////////////////////////////////////////////////////////////////
316
////////////////////////////////////////////////////////////////////////
317
318
319
320
//=========start_of_main=============================================
321
/// Driver for 3D Poisson problem in eighth of a sphere. Solution
322
/// has a sharp step. If there are
323
/// any command line arguments, we regard this as a validation run
324
/// and perform only a single adaptation.
325
//===================================================================
326
int
main
(
int
argc,
char
*argv[])
327
{
328
329
// Store command line arguments
330
CommandLineArgs::setup(argc,argv);
331
332
// Set up the problem with 27-node brick elements, pass pointer to
333
// source function
334
EighthSpherePoissonProblem<RefineableQPoissonElement<3,3>
>
335
problem(&
TanhSolnForPoisson::get_source
);
336
337
// Setup labels for output
338
DocInfo doc_info;
339
340
// Output directory
341
doc_info.set_directory(
"RESLT"
);
342
343
// Step number
344
doc_info.number()=0;
345
346
// Check if we're ready to go
347
cout <<
"Self test: "
<< problem.self_test() << std::endl;
348
349
// Solve the problem
350
problem.newton_solve();
351
352
//Output solution
353
problem.
doc_solution
(doc_info);
354
355
//Increment counter for solutions
356
doc_info.number()++;
357
358
// Now do (up to) three rounds of fully automatic adapation in response to
359
// error estimate
360
unsigned
max_solve;
361
if
(CommandLineArgs::Argc>1)
362
{
363
// Validation run: Just one adaptation
364
max_solve=1;
365
cout <<
"Only doing one adaptation for validation"
<< std::endl;
366
}
367
else
368
{
369
// Up to four adaptations
370
max_solve=4;
371
}
372
373
for
(
unsigned
isolve=0;isolve<max_solve;isolve++)
374
{
375
// Adapt problem/mesh
376
problem.adapt();
377
378
// Re-solve the problem if the adaptation has changed anything
379
if
((problem.
mesh_pt
()->nrefined() !=0)||
380
(problem.
mesh_pt
()->nunrefined()!=0))
381
{
382
problem.newton_solve();
383
}
384
else
385
{
386
cout <<
"Mesh wasn't adapted --> we'll stop here"
<< std::endl;
387
break
;
388
}
389
390
//Output solution
391
problem.
doc_solution
(doc_info);
392
393
//Increment counter for solutions
394
doc_info.number()++;
395
}
396
397
// pause("done");
398
399
}
// end of main
400
401
402
403
404
405
406
407
408
EighthSpherePoissonProblem
Poisson problem in refineable eighth of a sphere mesh.
Definition
eighth_sphere_poisson.cc:132
EighthSpherePoissonProblem::~EighthSpherePoissonProblem
~EighthSpherePoissonProblem()
Destructor: Empty.
Definition
eighth_sphere_poisson.cc:141
EighthSpherePoissonProblem::actions_after_newton_solve
void actions_after_newton_solve()
Update the problem specs after solve (empty)
Definition
eighth_sphere_poisson.cc:151
EighthSpherePoissonProblem::mesh_pt
RefineableEighthSphereMesh< ELEMENT > * mesh_pt()
Overload generic access function by one that returns a pointer to the specific mesh.
Definition
eighth_sphere_poisson.cc:145
EighthSpherePoissonProblem::doc_solution
void doc_solution(DocInfo &doc_info)
Doc the solution.
Definition
eighth_sphere_poisson.cc:271
EighthSpherePoissonProblem::EighthSpherePoissonProblem
EighthSpherePoissonProblem(PoissonEquations< 3 >::PoissonSourceFctPt source_fct_pt)
Constructor: Pass pointer to source function.
Definition
eighth_sphere_poisson.cc:195
EighthSpherePoissonProblem::Source_fct_pt
PoissonEquations< 3 >::PoissonSourceFctPt Source_fct_pt
Pointer to source function.
Definition
eighth_sphere_poisson.cc:183
EighthSpherePoissonProblem::actions_before_newton_solve
void actions_before_newton_solve()
Update the problem specs before solve: Set Dirchlet boundary conditions from exact solution.
Definition
eighth_sphere_poisson.cc:155
main
int main(int argc, char *argv[])
Driver for 3D Poisson problem in eighth of a sphere. Solution has a sharp step. If there are any comm...
Definition
eighth_sphere_poisson.cc:326
TanhSolnForPoisson
Namespace for exact solution for Poisson equation with sharp step.
Definition
eighth_sphere_poisson.cc:45
TanhSolnForPoisson::N_y
double N_y
Orientation (non-normalised y-component of unit vector in direction of step plane)
Definition
eighth_sphere_poisson.cc:56
TanhSolnForPoisson::Z_0
double Z_0
Orientation (z-coordinate of step plane)
Definition
eighth_sphere_poisson.cc:70
TanhSolnForPoisson::N_x
double N_x
Orientation (non-normalised x-component of unit vector in direction of step plane)
Definition
eighth_sphere_poisson.cc:52
TanhSolnForPoisson::Y_0
double Y_0
Orientation (y-coordinate of step plane)
Definition
eighth_sphere_poisson.cc:67
TanhSolnForPoisson::get_source
void get_source(const Vector< double > &x, double &source)
Source function to make it an exact solution.
Definition
eighth_sphere_poisson.cc:91
TanhSolnForPoisson::Alpha
double Alpha
Parameter for steepness of step.
Definition
eighth_sphere_poisson.cc:48
TanhSolnForPoisson::N_z
double N_z
Orientation (non-normalised z-component of unit vector in direction of step plane)
Definition
eighth_sphere_poisson.cc:60
TanhSolnForPoisson::X_0
double X_0
Orientation (x-coordinate of step plane)
Definition
eighth_sphere_poisson.cc:64
TanhSolnForPoisson::get_exact_u
void get_exact_u(const Vector< double > &x, Vector< double > &u)
Definition
eighth_sphere_poisson.cc:74