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-2023 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 
38 using namespace std;
39 
40 using namespace oomph;
41 
42 //=================================================================
43 /// Fish shaped mesh with simple adaptivity (no macro elements).
44 //=================================================================
45 template<class ELEMENT>
46 class SimpleRefineableFishMesh : public virtual FishMesh<ELEMENT>,
47  public RefineableQuadMesh<ELEMENT>
48 {
49 
50 
51 public:
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 //====================================================================
88 namespace ConstSourceForPoisson
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 //====================================================================
109 template<class ELEMENT>
111 {
112 
113 public:
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 //========================================================================
149 template<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 //========================================================================
201 template<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  sprintf(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 //========================================================================
232 int 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.
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)
SimpleRefineableFishMesh< ELEMENT > * mesh_pt()
Overloaded version of the problem's access function to the mesh. Recasts the pointer to the base Mesh...
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.