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
39using namespace std;
40
41using namespace oomph;
42
43//=============start_of_namespace=====================================
44/// Namespace for exact solution for Poisson equation with sharp step
45//====================================================================
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
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)*
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)*
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]-
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]-
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]-
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]-
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]-
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]-
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//====================================================================
127template<class ELEMENT>
128class PoissonProblem : public Problem
129{
130
131public:
132
133
134 /// Constructor
136 const string& node_file_name,
137 const string& element_file_name,
138 const string& face_file_name);
139
140 /// Destructor (empty)
142
143
144 /// Update the problem specs before solve: (Re)set boundary conditions
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);
162 nod_pt->set_value(0,u);
163 }
164 }
165 }
166
167 /// Update the problem specs before solve (empty)
169
170
171 //Access function for the specific mesh
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
180private:
181
182 /// Pointer to source function
184
185};
186
187
188
189//========================================================================
190/// Constructor for Poisson problem
191//========================================================================
192template<class ELEMENT>
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
205
206
207 //Create mesh
208 Problem::mesh_pt() = new TetgenMesh<ELEMENT>(node_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//========================================================================
251template<class ELEMENT>
254{
255
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//========================================================================
324int 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";
336 "Must specify the following file names \n";
337 error_message +=
338 "filename.node then filename.ele then filename.face\n";
339
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
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 {
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 {
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
Micky mouse Poisson problem.
void actions_before_newton_solve()
Update the problem specs before solve: (Re)set boundary conditions.
TetgenMesh< ELEMENT > * mesh_pt()
void actions_after_newton_solve()
Update the problem specs before solve (empty)
void doc_solution(const unsigned &nplot, DocInfo &doc_info)
Doc the solution.
~PoissonProblem()
Destructor (empty)
PoissonEquations< 3 >::PoissonSourceFctPt Source_fct_pt
Pointer to source function.
PoissonProblem(PoissonEquations< 3 >::PoissonSourceFctPt source_fct_pt, const string &node_file_name, const string &element_file_name, const string &face_file_name)
Constructor.
Unstructured tet mesh based on output from Tetgen: http://wias-berlin.de/software/tetgen/.
Definition tetgen_mesh.h:51
TetgenMesh()
Empty constructor.
Definition tetgen_mesh.h:54
int main(int argc, char *argv[])
3D Navier Stokes on an unstructured mesh
Namespace for exact solution for Poisson equation with sharp step.
double N_y
Orientation (non-normalised y-component of unit vector in direction of step plane)
double Z_0
Orientation (z-coordinate of step plane)
double N_x
Orientation (non-normalised x-component of unit vector in direction of step plane)
double Y_0
Orientation (y-coordinate of step plane)
void get_source(const Vector< double > &x, double &source)
Source function to make it an exact solution.
double Alpha
Parameter for steepness of step.
double N_z
Orientation (non-normalised z-component of unit vector in direction of step plane)
double X_0
Orientation (x-coordinate of step plane)
void get_exact_u(const Vector< double > &x, Vector< double > &u)