macro_element_free_boundary_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// 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 "free boundary" 2D Poisson equation in
31 // fish-shaped domain with adaptivity
32 
33 
34 // Generic oomph-lib headers
35 #include "generic.h"
36 
37 // The Poisson equations
38 #include "poisson.h"
39 
40 // The fish mesh
41 #include "meshes/fish_mesh.h"
42 
43 // Circle as generalised element:
45 
46 using namespace std;
47 
48 using namespace oomph;
49 
50 
51 ///////////////////////////////////////////////////////////////////////
52 ///////////////////////////////////////////////////////////////////////
53 ///////////////////////////////////////////////////////////////////////
54 
55 
56 
57 //=============start_of_namespace=====================================
58 /// Namespace for const source term in Poisson equation
59 //====================================================================
60 namespace ConstSourceForPoisson
61 {
62 
63 /// Const source function
64  void get_source(const Vector<double>& x, double& source)
65  {
66  source = -1.0;
67  }
68 
69 } // end of namespace
70 
71 
72 
73 
74 
75 
76 
77 ////////////////////////////////////////////////////////////////////
78 ////////////////////////////////////////////////////////////////////
79 // MacroElementNodeUpdate-version of RefineableFishMesh
80 ////////////////////////////////////////////////////////////////////
81 ////////////////////////////////////////////////////////////////////
82 
83 
84 
85 //==========start_of_mesh=================================================
86 /// Refineable, fish-shaped mesh with MacroElement-based node update.
87 //========================================================================
88 template<class ELEMENT>
90  public virtual RefineableFishMesh<ELEMENT>,
91  public virtual MacroElementNodeUpdateMesh
92 {
93 
94 public:
95 
96  /// \short Constructor: Pass pointer to GeomObject that defines
97  /// the fish's back and pointer to timestepper
98  /// (defaults to (Steady) default timestepper defined in the Mesh
99  /// base class).
101  TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper) :
102  FishMesh<ELEMENT>(back_pt,time_stepper_pt),
103  RefineableFishMesh<ELEMENT>(time_stepper_pt)
104  {
105  // Set up all the information that's required for MacroElement-based
106  // node update: Tell the elements that their geometry depends on the
107  // fishback geometric object.
108  unsigned n_element = this->nelement();
109  for(unsigned i=0;i<n_element;i++)
110  {
111  // Upcast from FiniteElement to the present element
112  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(this->element_pt(i));
113 
114  // There's just one GeomObject
115  Vector<GeomObject*> geom_object_pt(1);
116  geom_object_pt[0] = back_pt;
117 
118  // Tell the element which geom objects its macro-element-based
119  // node update depends on
120  el_pt->set_node_update_info(geom_object_pt);
121  }
122 
123  } //end of constructor
124 
125  /// \short Destructor: empty
127 
128  /// \short Resolve mesh update: Node update current nodal
129  /// positions via sparse MacroElement-based update.
130  //void node_update()
131  // {
132  // MacroElementNodeUpdateMesh::node_update();
133  // }
134 
135 }; // end of mesh class
136 
137 
138 
139 ////////////////////////////////////////////////////////////////////////
140 ////////////////////////////////////////////////////////////////////////
141 ////////////////////////////////////////////////////////////////////////
142 
143 
144 
145 //==========start_of_problem_class====================================
146 /// Refineable "free-boundary" Poisson problem in deformable
147 /// fish-shaped domain. Template parameter identifies the element.
148 //====================================================================
149 template<class ELEMENT>
150 class FreeBoundaryPoissonProblem : public Problem
151 {
152 
153 public:
154 
155  /// \short Constructor
157 
158  /// Destructor (empty)
160 
161  /// Update the problem specs before solve (empty)
163 
164  /// Update the problem specs after solve (empty)
166 
167  /// Access function for the fish mesh
169  {
170  return Fish_mesh_pt;
171  }
172 
173  /// Doc the solution
174  void doc_solution();
175 
176  /// \short Before checking the new residuals in Newton's method
177  /// we have to update nodal positions in response to possible
178  /// changes in the position of the domain boundary
180  {
181  fish_mesh_pt()->node_update();
182  }
183 
184 private:
185 
186  /// Pointer to fish mesh
188 
189  /// Pointer to single-element mesh that stores the GeneralisedElement
190  /// that represents the fish's back
192 
193 }; // end of problem class
194 
195 
196 
197 
198 //=========start_of_constructor===========================================
199 /// Constructor for adaptive free-boundary Poisson problem in
200 /// deformable fish-shaped domain.
201 //========================================================================
202 template<class ELEMENT>
204 {
205 
206  // Set coordinates and radius for the circle that will become the fish back
207  double x_c=0.5;
208  double y_c=0.0;
209  double r_back=1.0;
210 
211  // Build geometric object that will become the fish back
212  ElasticallySupportedRingElement* fish_back_pt=
213  new ElasticallySupportedRingElement(x_c,y_c,r_back);
214 
215  // Build fish mesh with geometric object that specifies the fish back
216  Fish_mesh_pt=new
218 
219  // Add the fish mesh to the problem's collection of submeshes:
220  add_sub_mesh(Fish_mesh_pt);
221 
222  // Create/set error estimator for the fish mesh
223  fish_mesh_pt()->spatial_error_estimator_pt()=new Z2ErrorEstimator;
224 
225  // Build mesh that will store only the geometric wall element
226  Fish_back_mesh_pt=new Mesh;
227 
228  // So far, the mesh is completely empty. Let's add the
229  // GeneralisedElement that represents the shape
230  // of the fish's back to it:
231  Fish_back_mesh_pt->add_element_pt(fish_back_pt);
232 
233  // Add the fish back mesh to the problem's collection of submeshes:
234  add_sub_mesh(Fish_back_mesh_pt);
235 
236  // Now build global mesh from the submeshes
237  build_global_mesh();
238 
239  // Choose a control node: We'll use the
240  // central node that is shared by all four elements in
241  // the base mesh because it exists at all refinement levels.
242 
243  // How many nodes does element 0 have?
244  unsigned nnod=fish_mesh_pt()->finite_element_pt(0)->nnode();
245 
246  // The central node is the last node in element 0:
247  Node* control_node_pt=fish_mesh_pt()->finite_element_pt(0)->node_pt(nnod-1);
248 
249  // Use the solution (value 0) at the control node as the load
250  // that acts on the ring. [Note: Node == Data by inheritance]
251  dynamic_cast<ElasticallySupportedRingElement*>(Fish_mesh_pt->fish_back_pt())->
252  set_load_pt(control_node_pt);
253 
254  // Set the boundary conditions for this problem: All nodes are
255  // free by default -- just pin the ones that have Dirichlet conditions
256  // here. Set homogeneous boundary conditions everywhere
257  unsigned num_bound = fish_mesh_pt()->nboundary();
258  for(unsigned ibound=0;ibound<num_bound;ibound++)
259  {
260  unsigned num_nod= fish_mesh_pt()->nboundary_node(ibound);
261  for (unsigned inod=0;inod<num_nod;inod++)
262  {
263  fish_mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
264  fish_mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,0.0);
265 
266  }
267  }
268 
269  /// Loop over elements and set pointers to source function
270  unsigned n_element = fish_mesh_pt()->nelement();
271  for(unsigned i=0;i<n_element;i++)
272  {
273  // Upcast from FiniteElement to the present element
274  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(fish_mesh_pt()->element_pt(i));
275 
276  //Set the source function pointer
277  el_pt->source_fct_pt() = &ConstSourceForPoisson::get_source;
278  }
279 
280  // Do equation numbering
281  cout << "Number of equations: " << assign_eqn_numbers() << std::endl;
282 
283 } // end of constructor
284 
285 
286 
287 
288 //============start_of_doc================================================
289 /// Doc the solution in tecplot format.
290 //========================================================================
291 template<class ELEMENT>
293 {
294 
295  // Number of plot points in each coordinate direction.
296  unsigned npts=5;
297 
298  // Output solution
299  ofstream some_file("RESLT/soln0.dat");
300  fish_mesh_pt()->output(some_file,npts);
301  some_file.close();
302 
303 } // end of doc
304 
305 
306 
307 
308 
309 //==================start_of_main=========================================
310 /// Driver for "free-boundary" fish poisson solver with adaptation.
311 //========================================================================
312 int main()
313 {
314 
315  // Shorthand for element type
316  typedef MacroElementNodeUpdateElement<RefineableQPoissonElement<2,3> >
317  ELEMENT;
318 
319  // Build problem
321 
322  // Do some uniform mesh refinement first
323  problem.refine_uniformly();
324  problem.refine_uniformly();
325 
326  // Solve/doc fully coupled problem, allowing for up to two spatial
327  // adaptations.
328  unsigned max_solve=2;
329  problem.newton_solve(max_solve);
330  problem.doc_solution();
331 
332 } // end of main
333 
334 
MyMacroElementNodeUpdateRefineableFishMesh< ELEMENT > * Fish_mesh_pt
Pointer to fish mesh.
MyMacroElementNodeUpdateRefineableFishMesh(GeomObject *back_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that defines the fish&#39;s back and pointer to timestepper (defa...
virtual ~FreeBoundaryPoissonProblem()
Destructor (empty)
MyMacroElementNodeUpdateRefineableFishMesh< ELEMENT > * fish_mesh_pt()
Access function for the fish mesh.
void actions_before_newton_convergence_check()
Before checking the new residuals in Newton&#39;s method we have to update nodal positions in response to...
Definition: circle.h:37
void get_source(const Vector< double > &x, double &source)
Const source function.
void actions_after_newton_solve()
Update the problem specs after solve (empty)
Refineable, fish-shaped mesh with MacroElement-based node update.
int main()
Driver for "free-boundary" fish poisson solver with adaptation.
Namespace for const source term in Poisson equation.
GeneralCircle "upgraded" to a GeneralisedElement: Circular ring whose position is given by The ring...
void actions_before_newton_solve()
Update the problem specs before solve (empty)