fish_poisson_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// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 // Driver for solution of 2D Poisson equation in fish-shaped domain with
31 // adaptivity
32 
33 // Generic oomph-lib headers
34 #include "generic.h"
35 
36 // The Poisson equations
37 #include "poisson.h"
38 
39 // The fish mesh
40 #include "meshes/fish_mesh.h"
41 
42 using namespace std;
43 
44 using namespace oomph;
45 
46 //============ start_of_namespace=====================================
47 /// Namespace for const source term in Poisson equation
48 //====================================================================
50 {
51 
52  /// Strength of source function: default value -1.0
53  double Strength=-1.0;
54 
55 /// Const source function
56  void get_source(const Vector<double>& x, double& source)
57  {
58  source = Strength;
59  }
60 
61 } // end of namespace
62 
63 
64 
65 
66 //======start_of_problem_class========================================
67 /// Refineable Poisson problem in fish-shaped domain.
68 /// Template parameter identifies the element type.
69 //====================================================================
70 template<class ELEMENT>
71 class RefineableFishPoissonProblem : public Problem
72 {
73 
74 public:
75 
76  /// Constructor
78 
79  /// Destructor: Empty
81 
82  /// Update the problem specs after solve (empty)
84 
85  /// Update the problem specs before solve (empty)
87 
88  /// \short Overloaded version of the problem's access function to
89  /// the mesh. Recasts the pointer to the base Mesh object to
90  /// the actual mesh type.
91  RefineableFishMesh<ELEMENT>* mesh_pt()
92  {
93  return dynamic_cast<RefineableFishMesh<ELEMENT>*>(Problem::mesh_pt());
94  }
95 
96  /// \short Doc the solution. Output directory and labels are specified
97  /// by DocInfo object
98  void doc_solution(DocInfo& doc_info);
99 
100 }; // end of problem class
101 
102 
103 
104 
105 
106 //===========start_of_constructor=========================================
107 /// Constructor for adaptive Poisson problem in fish-shaped
108 /// domain.
109 //========================================================================
110 template<class ELEMENT>
112 {
113 
114  // Build fish mesh -- this is a coarse base mesh consisting
115  // of four elements. We'll refine/adapt the mesh later.
116  Problem::mesh_pt()=new RefineableFishMesh<ELEMENT>;
117 
118  // Create/set error estimator
119  mesh_pt()->spatial_error_estimator_pt()=new Z2ErrorEstimator;
120 
121  // Set the boundary conditions for this problem: All nodes are
122  // free by default -- just pin the ones that have Dirichlet conditions
123  // here. Since the boundary values are never changed, we set
124  // them here rather than in actions_before_newton_solve().
125  unsigned num_bound = mesh_pt()->nboundary();
126 
127  for(unsigned ibound=0;ibound<num_bound;ibound++)
128  {
129  unsigned num_nod= mesh_pt()->nboundary_node(ibound);
130  for (unsigned inod=0;inod<num_nod;inod++)
131  {
132  // Pin the single scalar value at this node
133  mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
134 
135  // Assign the homogenous boundary condition to the one
136  // and only nodal value
137  mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,0.0);
138  }
139  }
140 
141  // Loop over elements and set pointers to source function
142  unsigned n_element = mesh_pt()->nelement();
143  for(unsigned i=0;i<n_element;i++)
144  {
145  // Upcast from FiniteElement to the present element
146  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
147 
148  //Set the source function pointer
149  el_pt->source_fct_pt() = &ConstSourceForPoisson::get_source;
150  }
151 
152  // Setup the equation numbering scheme
153  cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
154 
155 } // end of constructor
156 
157 
158 
159 
160 //=======start_of_doc=====================================================
161 /// Doc the solution in tecplot format.
162 //========================================================================
163 template<class ELEMENT>
165 {
166 
167  ofstream some_file;
168  char filename[100];
169 
170  // Number of plot points in each coordinate direction.
171  unsigned npts;
172  npts=5;
173 
174  // Output solution
175  sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
176  doc_info.number());
177  some_file.open(filename);
178  mesh_pt()->output(some_file,npts);
179  some_file.close();
180 
181 } // end of doc
182 
183 
184 
185 
186 
187 
188 //=====================start_of_incremental===============================
189 /// Demonstrate how to solve 2D Poisson problem in
190 /// fish-shaped domain with mesh adaptation. First we solve on the original
191 /// coarse mesh. Next we do a few uniform refinement steps and resolve.
192 /// Finally, we enter into an automatic adapation loop.
193 //========================================================================
195 {
196 
197  //Set up the problem with 4 node refineable Poisson elements
199 
200  // Setup labels for output
201  //------------------------
202  DocInfo doc_info;
203 
204  // Set output directory
205  doc_info.set_directory("RESLT");
206 
207  // Step number
208  doc_info.number()=0;
209 
210 
211  // Doc (default) refinement targets
212  //----------------------------------
213  problem.mesh_pt()->doc_adaptivity_targets(cout);
214 
215  // Solve/doc the problem on the initial, very coarse mesh
216  //-------------------------------------------------------
217 
218  // Solve the problem
219  problem.newton_solve();
220 
221  //Output solution
222  problem.doc_solution(doc_info);
223 
224  //Increment counter for solutions
225  doc_info.number()++;
226 
227 
228  // Do three rounds of uniform mesh refinement and re-solve
229  //--------------------------------------------------------
230  unsigned n_uniform=3;
231  for (unsigned isolve=0;isolve<n_uniform;isolve++)
232  {
233 
234  // Refine the problem uniformly
235  problem.refine_uniformly();
236 
237  // Solve the problem
238  problem.newton_solve();
239 
240  //Output solution
241  problem.doc_solution(doc_info);
242 
243  //Increment counter for solutions
244  doc_info.number()++;
245  }
246 
247 
248  // Now do (up to) four rounds of fully automatic adapation in response to
249  //-----------------------------------------------------------------------
250  // error estimate
251  //---------------
252  unsigned max_solve=4;
253  for (unsigned isolve=0;isolve<max_solve;isolve++)
254  {
255  // Adapt problem/mesh
256  problem.adapt();
257 
258  // Re-solve the problem if the adaptation has changed anything
259  if ((problem.mesh_pt()->nrefined() !=0)||
260  (problem.mesh_pt()->nunrefined()!=0))
261  {
262  problem.newton_solve();
263  }
264  else
265  {
266  cout << "Mesh wasn't adapted --> we'll stop here" << std::endl;
267  break;
268  }
269 
270  //Output solution
271  problem.doc_solution(doc_info);
272 
273  //Increment counter for solutions
274  doc_info.number()++;
275  }
276 
277 
278 } // end of incremental
279 
280 
281 //=================start_of_main==========================================
282 /// Demonstrate how to solve 2D Poisson problem in
283 /// fish-shaped domain with mesh adaptation.
284 //========================================================================
285 int main()
286 {
287  // Solve with adaptation, docing the intermediate steps
289 
290 } // end of main
291 
void actions_after_newton_solve()
Update the problem specs after solve (empty)
int main()
double Strength
Strength of source function: default value -1.0.
virtual ~RefineableFishPoissonProblem()
Destructor: Empty.
void get_source(const Vector< double > &x, double &source)
Const source function.
void actions_before_newton_solve()
Update the problem specs before solve (empty)
void solve_with_incremental_adaptation()
void doc_solution(DocInfo &doc_info)
Doc the solution. Output directory and labels are specified by DocInfo object.
Namespace for const source term in Poisson equation.
RefineableFishMesh< ELEMENT > * mesh_pt()
Overloaded version of the problem&#39;s access function to the mesh. Recasts the pointer to the base Mesh...