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