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