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
two_d_poisson
two_d_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 simple 2D 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/simple_rectangular_quadmesh.h"
36
37
using namespace
std;
38
39
using namespace
oomph
;
40
41
42
//===== start_of_namespace=============================================
43
/// Namespace for exact solution for Poisson equation with "sharp step"
44
//=====================================================================
45
namespace
TanhSolnForPoisson
46
{
47
48
/// Parameter for steepness of "step"
49
double
Alpha
=1.0;
50
51
/// Parameter for angle Phi of "step"
52
double
TanPhi
=0.0;
53
54
/// Exact solution as a Vector
55
void
get_exact_u
(
const
Vector<double>& x, Vector<double>& u)
56
{
57
u[0]=tanh(1.0-
Alpha
*(
TanPhi
*x[0]-x[1]));
58
}
59
60
/// Source function required to make the solution above an exact solution
61
void
source_function
(
const
Vector<double>& x,
double
& source)
62
{
63
source = 2.0*tanh(-1.0+
Alpha
*(
TanPhi
*x[0]-x[1]))*
64
(1.0-pow(tanh(-1.0+
Alpha
*(
TanPhi
*x[0]-x[1])),2.0))*
65
Alpha
*
Alpha
*
TanPhi
*
TanPhi
+2.0*tanh(-1.0+
Alpha
*(
TanPhi
*x[0]-x[1]))*
66
(1.0-pow(tanh(-1.0+
Alpha
*(
TanPhi
*x[0]-x[1])),2.0))*
Alpha
*
Alpha
;
67
}
68
69
}
// end of namespace
70
71
72
73
74
75
76
77
78
//====== start_of_problem_class=======================================
79
/// 2D Poisson problem on rectangular domain, discretised with
80
/// 2D QPoisson elements. The specific type of element is
81
/// specified via the template parameter.
82
//====================================================================
83
template
<
class
ELEMENT>
84
class
PoissonProblem
:
public
Problem
85
{
86
87
public
:
88
89
/// Constructor: Pass pointer to source function
90
PoissonProblem
(PoissonEquations<2>::PoissonSourceFctPt source_fct_pt);
91
92
/// Destructor (empty)
93
~PoissonProblem
(){}
94
95
/// Update the problem specs before solve: Reset boundary conditions
96
/// to the values from the exact solution.
97
void
actions_before_newton_solve
();
98
99
/// Update the problem after solve (empty)
100
void
actions_after_newton_solve
(){}
101
102
/// Doc the solution. DocInfo object stores flags/labels for where the
103
/// output gets written to
104
void
doc_solution
(DocInfo& doc_info);
105
106
private
:
107
108
/// Pointer to source function
109
PoissonEquations<2>::PoissonSourceFctPt
Source_fct_pt
;
110
111
};
// end of problem class
112
113
114
115
116
//=====start_of_constructor===============================================
117
/// Constructor for Poisson problem: Pass pointer to source function.
118
//========================================================================
119
template
<
class
ELEMENT>
120
PoissonProblem<ELEMENT>::
121
PoissonProblem
(PoissonEquations<2>::PoissonSourceFctPt source_fct_pt)
122
: Source_fct_pt(source_fct_pt)
123
{
124
// Setup mesh
125
126
// # of elements in x-direction
127
unsigned
n_x=4;
128
129
// # of elements in y-direction
130
unsigned
n_y=4;
131
132
// Domain length in x-direction
133
double
l_x=1.0;
134
135
// Domain length in y-direction
136
double
l_y=2.0;
137
138
// Build and assign mesh
139
Problem::mesh_pt() =
new
SimpleRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
140
141
// Set the boundary conditions for this problem: All nodes are
142
// free by default -- only need to pin the ones that have Dirichlet conditions
143
// here.
144
unsigned
n_bound = mesh_pt()->nboundary();
145
for
(
unsigned
i=0;i<n_bound;i++)
146
{
147
unsigned
n_node = mesh_pt()->nboundary_node(i);
148
for
(
unsigned
n=0;n<n_node;n++)
149
{
150
mesh_pt()->boundary_node_pt(i,n)->pin(0);
151
}
152
}
153
154
// Complete the build of all elements so they are fully functional
155
156
// Loop over the elements to set up element-specific
157
// things that cannot be handled by the (argument-free!) ELEMENT
158
// constructor: Pass pointer to source function
159
unsigned
n_element = mesh_pt()->nelement();
160
for
(
unsigned
i=0;i<n_element;i++)
161
{
162
// Upcast from GeneralsedElement to the present element
163
ELEMENT *el_pt =
dynamic_cast<
ELEMENT*
>
(mesh_pt()->element_pt(i));
164
165
//Set the source function pointer
166
el_pt->source_fct_pt() =
Source_fct_pt
;
167
}
168
169
170
// Setup equation numbering scheme
171
cout <<
"Number of equations: "
<< assign_eqn_numbers() << std::endl;
172
173
}
// end of constructor
174
175
176
177
178
//========================================start_of_actions_before_newton_solve===
179
/// Update the problem specs before solve: (Re-)set boundary conditions
180
/// to the values from the exact solution.
181
//========================================================================
182
template
<
class
ELEMENT>
183
void
PoissonProblem<ELEMENT>::actions_before_newton_solve
()
184
{
185
// How many boundaries are there?
186
unsigned
n_bound = mesh_pt()->nboundary();
187
188
//Loop over the boundaries
189
for
(
unsigned
i=0;i<n_bound;i++)
190
{
191
// How many nodes are there on this boundary?
192
unsigned
n_node = mesh_pt()->nboundary_node(i);
193
194
// Loop over the nodes on boundary
195
for
(
unsigned
n=0;n<n_node;n++)
196
{
197
// Get pointer to node
198
Node* nod_pt=mesh_pt()->boundary_node_pt(i,n);
199
200
// Extract nodal coordinates from node:
201
Vector<double> x(2);
202
x[0]=nod_pt->x(0);
203
x[1]=nod_pt->x(1);
204
205
// Compute the value of the exact solution at the nodal point
206
Vector<double> u(1);
207
TanhSolnForPoisson::get_exact_u
(x,u);
208
209
// Assign the value to the one (and only) nodal value at this node
210
nod_pt->set_value(0,u[0]);
211
}
212
}
213
}
// end of actions before solve
214
215
216
217
//===============start_of_doc=============================================
218
/// Doc the solution: doc_info contains labels/output directory etc.
219
//========================================================================
220
template
<
class
ELEMENT>
221
void
PoissonProblem<ELEMENT>::doc_solution
(DocInfo& doc_info)
222
{
223
224
ofstream some_file;
225
char
filename[100];
226
227
// Number of plot points: npts x npts
228
unsigned
npts=5;
229
230
// Output solution
231
//-----------------
232
snprintf(filename,
sizeof
(filename),
"%s/soln%i.dat"
,doc_info.directory().c_str(),
233
doc_info.number());
234
some_file.open(filename);
235
mesh_pt()->output(some_file,npts);
236
some_file.close();
237
238
239
// Output exact solution
240
//----------------------
241
snprintf(filename,
sizeof
(filename),
"%s/exact_soln%i.dat"
,doc_info.directory().c_str(),
242
doc_info.number());
243
some_file.open(filename);
244
mesh_pt()->output_fct(some_file,npts,
TanhSolnForPoisson::get_exact_u
);
245
some_file.close();
246
247
// Doc error and return of the square of the L2 error
248
//---------------------------------------------------
249
double
error,norm;
250
snprintf(filename,
sizeof
(filename),
"%s/error%i.dat"
,doc_info.directory().c_str(),
251
doc_info.number());
252
some_file.open(filename);
253
mesh_pt()->compute_error(some_file,
TanhSolnForPoisson::get_exact_u
,
254
error,norm);
255
some_file.close();
256
257
// Doc L2 error and norm of solution
258
cout <<
"\nNorm of error : "
<< sqrt(error) << std::endl;
259
cout <<
"Norm of solution: "
<< sqrt(norm) << std::endl << std::endl;
260
261
}
// end of doc
262
263
264
265
266
267
268
//===== start_of_main=====================================================
269
/// Driver code for 2D Poisson problem
270
//========================================================================
271
int
main
()
272
{
273
274
//Set up the problem
275
//------------------
276
277
// Create the problem with 2D nine-node elements from the
278
// QPoissonElement family. Pass pointer to source function.
279
PoissonProblem<QPoissonElement<2,3>
>
280
problem(&
TanhSolnForPoisson::source_function
);
281
282
// Create label for output
283
//------------------------
284
DocInfo doc_info;
285
286
// Set output directory
287
doc_info.set_directory(
"RESLT"
);
288
289
// Step number
290
doc_info.number()=0;
291
292
// Check that we're ready to go:
293
//----------------------------
294
cout <<
"\n\n\nProblem self-test "
;
295
if
(problem.self_test()==0)
296
{
297
cout <<
"passed: Problem can be solved."
<< std::endl;
298
}
299
else
300
{
301
throw
OomphLibError(
"Self test failed"
,
302
OOMPH_CURRENT_FUNCTION,
303
OOMPH_EXCEPTION_LOCATION);
304
}
305
306
307
// Set the orientation of the "step" to 45 degrees
308
TanhSolnForPoisson::TanPhi
=1.0;
309
310
// Initial value for the steepness of the "step"
311
TanhSolnForPoisson::Alpha
=1.0;
312
313
314
// Do a couple of solutions for different forcing functions
315
//---------------------------------------------------------
316
unsigned
nstep=4;
317
for
(
unsigned
istep=0;istep<nstep;istep++)
318
{
319
320
// Increase the steepness of the step:
321
TanhSolnForPoisson::Alpha
+=1.0;
322
323
cout <<
"\n\nSolving for TanhSolnForPoisson::Alpha="
324
<<
TanhSolnForPoisson::Alpha
<< std::endl << std::endl;
325
326
// Solve the problem
327
problem.newton_solve();
328
329
//Output the solution
330
problem.
doc_solution
(doc_info);
331
332
//Increment counter for solutions
333
doc_info.number()++;
334
335
}
336
337
338
}
//end of main
339
340
341
342
343
344
345
346
347
PoissonProblem
2D Poisson problem on rectangular domain, discretised with 2D QPoisson elements. The specific type of...
Definition
two_d_poisson.cc:85
PoissonProblem::Source_fct_pt
PoissonEquations< 2 >::PoissonSourceFctPt Source_fct_pt
Pointer to source function.
Definition
two_d_poisson.cc:109
PoissonProblem::actions_before_newton_solve
void actions_before_newton_solve()
Update the problem specs before solve: Reset boundary conditions to the values from the exact solutio...
Definition
two_d_poisson.cc:183
PoissonProblem::actions_after_newton_solve
void actions_after_newton_solve()
Update the problem after solve (empty)
Definition
two_d_poisson.cc:100
PoissonProblem::PoissonProblem
PoissonProblem(PoissonEquations< 2 >::PoissonSourceFctPt source_fct_pt)
Constructor: Pass pointer to source function.
Definition
two_d_poisson.cc:121
PoissonProblem::doc_solution
void doc_solution(DocInfo &doc_info)
Doc the solution. DocInfo object stores flags/labels for where the output gets written to.
Definition
two_d_poisson.cc:221
PoissonProblem::~PoissonProblem
~PoissonProblem()
Destructor (empty)
Definition
two_d_poisson.cc:93
TanhSolnForPoisson
Namespace for exact solution for Poisson equation with "sharp step".
Definition
two_d_poisson.cc:46
TanhSolnForPoisson::TanPhi
double TanPhi
Parameter for angle Phi of "step".
Definition
two_d_poisson.cc:52
TanhSolnForPoisson::source_function
void source_function(const Vector< double > &x, double &source)
Source function required to make the solution above an exact solution.
Definition
two_d_poisson.cc:61
TanhSolnForPoisson::Alpha
double Alpha
Parameter for steepness of "step".
Definition
two_d_poisson.cc:49
TanhSolnForPoisson::get_exact_u
void get_exact_u(const Vector< double > &x, Vector< double > &u)
Exact solution as a Vector.
Definition
two_d_poisson.cc:55
oomph
Definition
two_d_poisson2_mesh.cc:41
main
int main()
Driver code for 2D Poisson problem.
Definition
two_d_poisson.cc:271