fish_poisson_simple_adapt.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 solution of 2D Poisson equation in fish-shaped domain with
27// simple adaptivity (no macro elements)
28
29// Generic oomph-lib headers
30#include "generic.h"
31
32// The Poisson equations
33#include "poisson.h"
34
35// The fish mesh
36#include "meshes/fish_mesh.h"
37
38using namespace std;
39
40using namespace oomph;
41
42//=================================================================
43/// Fish shaped mesh with simple adaptivity (no macro elements).
44//=================================================================
45template<class ELEMENT>
46class SimpleRefineableFishMesh : public virtual FishMesh<ELEMENT>,
47 public RefineableQuadMesh<ELEMENT>
48{
49
50
51public:
52
53
54 /// Constructor: Pass pointer to timestepper
55 /// (defaults to (Steady) default timestepper defined in Mesh)
56 SimpleRefineableFishMesh(TimeStepper* time_stepper_pt=
57 &Mesh::Default_TimeStepper) :
58 FishMesh<ELEMENT>(time_stepper_pt)
59 {
60
61 // Setup quadtree forest
62 this->setup_quadtree_forest();
63
64 // Loop over all elements and null out macro element pointer
65 unsigned n_element=this->nelement();
66 for (unsigned e=0;e<n_element;e++)
67 {
68 // Get pointer to element
69 FiniteElement* el_pt=this->finite_element_pt(e);
70
71 // Null out the pointer to macro elements to disable them
72 el_pt->set_macro_elem_pt(0);
73 }
74 }
75
76
77 /// Destructor: Empty
79
80};
81
82
83
84
85//============ start_of_namespace=====================================
86/// Namespace for const source term in Poisson equation
87//====================================================================
89{
90
91 /// Strength of source function: default value -1.0
92 double Strength=-1.0;
93
94/// Const source function
95 void get_source(const Vector<double>& x, double& source)
96 {
97 source = Strength;
98 }
99
100} // end of namespace
101
102
103
104
105//======start_of_problem_class========================================
106/// Poisson problem in fish-shaped domain.
107/// Template parameter identifies the element type.
108//====================================================================
109template<class ELEMENT>
111{
112
113public:
114
115 /// Constructor
117
118 /// Destructor: Empty
120
121 /// Update the problem specs after solve (empty)
123
124 /// Update the problem specs before solve (empty)
126
127 /// Overloaded version of the problem's access function to
128 /// the mesh. Recasts the pointer to the base Mesh object to
129 /// the actual mesh type.
131 {
132 return dynamic_cast<SimpleRefineableFishMesh<ELEMENT>*>(Problem::mesh_pt());
133 }
134
135 /// Doc the solution. Output directory and labels are specified
136 /// by DocInfo object
137 void doc_solution(DocInfo& doc_info);
138
139}; // end of problem class
140
141
142
143
144
145//===========start_of_constructor=========================================
146/// Constructor for adaptive Poisson problem in fish-shaped
147/// domain.
148//========================================================================
149template<class ELEMENT>
151{
152
153 // Build fish mesh -- this is a coarse base mesh consisting
154 // of four elements.
155 Problem::mesh_pt()=new SimpleRefineableFishMesh<ELEMENT>;
156
157 // Create/set error estimator
158 mesh_pt()->spatial_error_estimator_pt()=new Z2ErrorEstimator;
159
160 // Set the boundary conditions for this problem: All nodes are
161 // free by default -- just pin the ones that have Dirichlet conditions
162 // here. Since the boundary values are never changed, we set
163 // them here rather than in actions_before_newton_solve().
164 unsigned num_bound = mesh_pt()->nboundary();
165 for(unsigned ibound=0;ibound<num_bound;ibound++)
166 {
167 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
168 for (unsigned inod=0;inod<num_nod;inod++)
169 {
170 // Pin the single scalar value at this node
171 mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
172
173 // Assign the homogenous boundary condition to the one
174 // and only nodal value
175 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,0.0);
176 }
177 }
178
179 // Loop over elements and set pointers to source function
180 unsigned n_element = mesh_pt()->nelement();
181 for(unsigned i=0;i<n_element;i++)
182 {
183 // Upcast from FiniteElement to the present element
184 ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
185
186 //Set the source function pointer
187 el_pt->source_fct_pt() = &ConstSourceForPoisson::get_source;
188 }
189
190 // Setup the equation numbering scheme
191 cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
192
193} // end of constructor
194
195
196
197
198//=======start_of_doc=====================================================
199/// Doc the solution in tecplot format.
200//========================================================================
201template<class ELEMENT>
203{
204
205 ofstream some_file;
206 char filename[100];
207
208 // Number of plot points in each coordinate direction.
209 unsigned npts;
210 npts=5;
211
212 // Output solution
213 snprintf(filename, sizeof(filename), "%s/soln%i.dat",doc_info.directory().c_str(),
214 doc_info.number());
215 some_file.open(filename);
216 mesh_pt()->output(some_file,npts);
217 some_file.close();
218
219} // end of doc
220
221
222
223
224
225
226//=====================start_of_main======================================
227/// Demonstrate how to solve 2D Poisson problem in
228/// fish-shaped domain with mesh adaptation. First we solve on the original
229/// coarse mesh. Next we do a few uniform refinement steps and resolve.
230/// Finally, we enter into an automatic adapation loop.
231//========================================================================
232int main()
233{
234
235 //Set up the problem with 4 node Poisson elements
237
238 // Setup labels for output
239 //------------------------
240 DocInfo doc_info;
241
242 // Set output directory
243 doc_info.set_directory("RESLT");
244
245 // Step number
246 doc_info.number()=0;
247
248
249 // Doc adaptivity targets
250 //-----------------------
251 problem.mesh_pt()->doc_adaptivity_targets(cout);
252
253
254 // Solve/doc the problem
255 //----------------------
256
257 // Solve the problem
258 problem.newton_solve();
259
260 //Output solution
261 problem.doc_solution(doc_info);
262
263 //Increment counter for solutions
264 doc_info.number()++;
265
266
267 // Do two rounds of uniform mesh refinement and re-solve
268 //-------------------------------------------------------
269 problem.refine_uniformly();
270 problem.refine_uniformly();
271
272 // Solve the problem
273 problem.newton_solve();
274
275 //Output solution
276 problem.doc_solution(doc_info);
277
278 //Increment counter for solutions
279 doc_info.number()++;
280
281
282 // Now do (up to) four rounds of fully automatic adapation in response to
283 //-----------------------------------------------------------------------
284 // error estimate
285 //---------------
286 unsigned max_solve=4;
287 for (unsigned isolve=0;isolve<max_solve;isolve++)
288 {
289 // Adapt problem/mesh
290 problem.adapt();
291
292 // Re-solve the problem if the adaptation has changed anything
293 if ((problem.mesh_pt()->nrefined() !=0)||
294 (problem.mesh_pt()->nunrefined()!=0))
295 {
296 problem.newton_solve();
297 }
298 else
299 {
300 cout << "Mesh wasn't adapted --> we'll stop here" << std::endl;
301 break;
302 }
303
304 //Output solution
305 problem.doc_solution(doc_info);
306
307 //Increment counter for solutions
308 doc_info.number()++;
309 }
310
311
312} // end of main
313
314
315
Fish shaped mesh with simple adaptivity (no macro elements).
virtual ~SimpleRefineableFishMesh()
Destructor: Empty.
SimpleRefineableFishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to timestepper (defaults to (Steady) default timestepper defined in Mesh)
Poisson problem in fish-shaped domain. Template parameter identifies the element type.
SimpleRefineableFishMesh< ELEMENT > * mesh_pt()
Overloaded version of the problem's access function to the mesh. Recasts the pointer to the base Mesh...
void doc_solution(DocInfo &doc_info)
Doc the solution. Output directory and labels are specified by DocInfo object.
void actions_after_newton_solve()
Update the problem specs after solve (empty)
virtual ~SimpleRefineableFishPoissonProblem()
Destructor: Empty.
void actions_before_newton_solve()
Update the problem specs before solve (empty)
int main()
Demonstrate how to solve 2D Poisson problem in fish-shaped domain with mesh adaptation....
Namespace for const source term in Poisson equation.
void get_source(const Vector< double > &x, double &source)
Const source function.
double Strength
Strength of source function: default value -1.0.