channel_with_leaflet_mesh.template.h
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 #ifndef OOMPH_CHANNEL_WITH_LEAFLET_MESH_HEADER
31 #define OOMPH_CHANNEL_WITH_LEAFLET_MESH_HEADER
32 
33 // Generic includes
34 #include "../generic/refineable_quad_mesh.h"
35 #include "../generic/macro_element.h"
36 #include "../generic/domain.h"
37 #include "../generic/quad_mesh.h"
38 
39 // Mesh is based on simple_rectangular_quadmesh
42 
43 //Include macro elements
44 #include "../generic/macro_element_node_update_element.h"
45 
46 //and algebraic elements
47 #include "../generic/algebraic_elements.h"
48 
49 //Include the headers file for domain
51 
52 namespace oomph
53 {
54 
55 //===================================================================
56 /// Channel with leaflet mesh
57 //===================================================================
58 template <class ELEMENT>
60 {
61  public:
62 
63 
64  ///\short Constructor: Pass pointer to GeomObject that represents the leaflet,
65  /// the length of the domain to left and right of the leaflet, the
66  /// height of the leaflet and the overall height of the channel,
67  /// the number of element columns to the left and right of the leaflet,
68  /// the number of rows of elements from the bottom of the channel to
69  /// the end of the leaflet, the number of rows of elements above the
70  /// end of the leaflet. Timestepper defaults to Steady default
71  /// Timestepper defined in the Mesh base class
72  ChannelWithLeafletMesh(GeomObject* leaflet_pt, const double& lleft,
73  const double& lright, const double& hleaflet,
74  const double& htot,
75  const unsigned& nleft, const unsigned& nright,
76  const unsigned& ny1, const unsigned& ny2,
77  TimeStepper* time_stepper_pt=
78  &Mesh::Default_TimeStepper);
79 
80  ///Destructor : empty
82 
83  /// Access function to domain
85 
86 protected:
87 
88  /// Pointer to domain
90 
91  /// Pointer to GeomObject that represents the leaflet
92  GeomObject * Leaflet_pt;
93 
94 };
95 
96 
97 /////////////////////////////////////////////////////////////////////
98 /////////////////////////////////////////////////////////////////////
99 /////////////////////////////////////////////////////////////////////
100 
101 
102 
103 //===================================================================
104 /// Refineable version of ChannelWithLeafletMesh
105 //===================================================================
106 template <class ELEMENT>
108 public virtual ChannelWithLeafletMesh<ELEMENT>,
109  public RefineableQuadMesh<ELEMENT>
110 {
111  public:
112 
113  ///\short Constructor: Pass pointer to GeomObject that represents the leaflet,
114  /// the length of the domain to left and right of the leaflet, the
115  /// height of the leaflet and the overall height of the channel,
116  /// the number of element columns to the left and right of the leaflet,
117  /// the number of rows of elements from the bottom of the channel to
118  /// the end of the leaflet, the number of rows of elements above the
119  /// end of the leaflet. Timestepper defaults to Steady default
120  /// Timestepper defined in the Mesh base class
121  RefineableChannelWithLeafletMesh(GeomObject* leaflet_pt,
122  const double& lleft,const double& lright,
123  const double& hleaflet,const double& htot,
124  const unsigned& nleft,const unsigned& nright,
125  const unsigned& ny1,const unsigned& ny2,
126  TimeStepper* time_stepper_pt=
127  &Mesh::Default_TimeStepper):
128  ChannelWithLeafletMesh<ELEMENT>(leaflet_pt,lleft,lright,hleaflet,htot,
129  nleft,nright,ny1,ny2,
130  time_stepper_pt)
131  {
132  // Build quadtree forest
133  this->setup_quadtree_forest();
134  }
135 
136  /// Destructor (empty)
138 
139 };
140 
141 
142 
143 /////////////////////////////////////////////////////////////////////
144 /////////////////////////////////////////////////////////////////////
145 /////////////////////////////////////////////////////////////////////
146 
147 
148 //=====start_of_mesh=======================================================
149 /// Channel with leaflet mesh with MacroElement-based node update.
150 /// The leaflet is represented by the specified geometric object.
151 /// Some or all of the geometric Data in that geometric object
152 /// may contain unknowns in the global Problem. The dependency
153 /// on these unknowns is taken into account when setting up
154 /// the Jacobian matrix of the elements. For this purpose,
155 /// the element (whose type is specified by the template parameter)
156 /// must inherit from MacroElementNodeUpdateElementBase.
157 //========================================================================
158 template<class ELEMENT>
160 public virtual MacroElementNodeUpdateMesh,
161  public virtual ChannelWithLeafletMesh<ELEMENT>
162 {
163 
164  public:
165 
166  ///\short Constructor: Pass pointer to GeomObject that represents the leaflet,
167  /// the length of the domain to left and right of the leaflet, the
168  /// height of the leaflet and the overall height of the channel,
169  /// the number of element columns to the left and right of the leaflet,
170  /// the number of rows of elements from the bottom of the channel to
171  /// the end of the leaflet, the number of rows of elements above the
172  /// end of the leaflet. Timestepper defaults to Steady default
173  /// Timestepper defined in the Mesh base class
175  GeomObject* leaflet_pt, const double& lleft,
176  const double& lright, const double& hleaflet,
177  const double& htot,
178  const unsigned& nleft, const unsigned& nright,
179  const unsigned& ny1, const unsigned& ny2,
180  TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper) :
181  ChannelWithLeafletMesh<ELEMENT>(leaflet_pt,lleft,lright,hleaflet,htot,
182  nleft,nright,ny1,ny2,
183  time_stepper_pt)
184  {
185 #ifdef PARANOID
186  ELEMENT* el_pt=new ELEMENT;
187  if (dynamic_cast<MacroElementNodeUpdateElementBase*>(el_pt)==0)
188  {
189  std::ostringstream error_message;
190  error_message
191  << "Base class for ELEMENT in "
192  << "MacroElementNodeUpdateChannelWithLeafletMesh needs"
193  << "to be of type MacroElementNodeUpdateElement!\n";
194  error_message << "Whereas it is: typeid(el_pt).name()"
195  << typeid(el_pt).name()
196  << std::endl;
197 
198  std::string function_name =
199  "MacroElementNodeUpdateChannelWithLeafletMesh::\n";
200  function_name +=
201  "MacroElementNodeUpdateChannelWithLeafletMesh()";
202 
203  throw OomphLibError(error_message.str(),
204  OOMPH_CURRENT_FUNCTION,
205  OOMPH_EXCEPTION_LOCATION);
206  }
207  delete el_pt;
208 #endif
209 
210  // Setup all the information that's required for MacroElement-based
211  // node update: Tell the elements that their geometry depends on the
212  // wall geometric object
213  unsigned n_element = this->nelement();
214  for(unsigned i=0;i<n_element;i++)
215  {
216  // Upcast from FiniteElement to the present element
217  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(this->element_pt(i));
218 
219 #ifdef PARANOID
220  // Check if cast is successful
221  MacroElementNodeUpdateElementBase* m_el_pt=dynamic_cast<
222  MacroElementNodeUpdateElementBase*>(el_pt);
223  if (m_el_pt==0)
224  {
225  std::ostringstream error_message;
226  error_message
227  << "Failed to upcast to MacroElementNodeUpdateElementBase\n";
228  error_message
229  << "Element must be derived from MacroElementNodeUpdateElementBase\n";
230  error_message << "but it is of type " << typeid(el_pt).name();
231 
232  std::string function_name =
233  "MacroElementNodeUpdateChannelWithLeafletMesh::\n";
234  function_name +=
235  "MacroElementNodeUpdateChannelWithLeafletMesh()";
236 
237  throw OomphLibError(error_message.str(),
238  OOMPH_CURRENT_FUNCTION,
239  OOMPH_EXCEPTION_LOCATION);
240  }
241 #endif
242 
243  // There's just one GeomObject
244  Vector<GeomObject*> geom_object_pt(1);
245  geom_object_pt[0] = this->Leaflet_pt;
246 
247  // Tell the element which geom objects its macro-element-based
248  // node update depends on
249  el_pt->set_node_update_info(geom_object_pt);
250  }
251 
252  // Add the geometric object(s) for the wall to the mesh's storage
253  Vector<GeomObject*> geom_object_pt(1);
254  geom_object_pt[0] = this->Leaflet_pt;
255  MacroElementNodeUpdateMesh::set_geom_object_vector_pt(geom_object_pt);
256 
257  // Fill in the domain pointer to the mesh's storage in the base class
258  MacroElementNodeUpdateMesh::macro_domain_pt()=this->domain_pt();
259 
260  } // end of constructor
261 
262 
263  /// \short Destructor: empty
265 
266 
267 }; //end of mesh
268 
269 
270 
271 
272 ////////////////////////////////////////////////////////////////////////////
273 ////////////////////////////////////////////////////////////////////////////
274 ////////////////////////////////////////////////////////////////////////////
275 
276 
277 //=====start_of_mesh=======================================================
278 /// Refineable mesh with MacroElement-based node update.
279 //========================================================================
280 template<class ELEMENT>
282  public virtual MacroElementNodeUpdateChannelWithLeafletMesh<ELEMENT>,
283  public virtual RefineableQuadMesh<ELEMENT>
284 {
285 
286 public:
287 
288  ///\short Constructor: Pass pointer to GeomObject that represents the leaflet,
289  /// the length of the domain to left and right of the leaflet, the
290  /// height of the leaflet and the overall height of the channel,
291  /// the number of element columns to the left and right of the leaflet,
292  /// the number of rows of elements from the bottom of the channel to
293  /// the end of the leaflet, the number of rows of elements above the
294  /// end of the leaflet. Timestepper defaults to Steady default
295  /// Timestepper defined in the Mesh base class
297  GeomObject* leaflet_pt, const double& lleft,
298  const double& lright, const double& hleaflet,
299  const double& htot,
300  const unsigned& nleft, const unsigned& nright,
301  const unsigned& ny1, const unsigned& ny2,
302  TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper) :
303  ChannelWithLeafletMesh<ELEMENT>(leaflet_pt,lleft,lright,hleaflet,htot,
304  nleft,nright,ny1,ny2,
305  time_stepper_pt),
307  leaflet_pt,lleft,lright,hleaflet,htot,
308  nleft,nright,ny1,ny2,
309  time_stepper_pt)
310  {
311  // Build quadtree forest
312  this->setup_quadtree_forest();
313  }
314 
315 
316  /// \short Destructor: empty
318 
319  }; //end of mesh
320 
321 
322 ///////////////////////////////////////////////////////////////////////
323 //////////////////////////////////////////////////////////////////////
324 ///////////////////////////////////////////////////////////////////////
325 
326 
327 //=================================================================
328 /// Algebraic version of ChannelWithLeafletMesh. Leaflet is
329 /// assumed to be in its undeformed (straight vertical) position
330 /// when the algebraic node update is set up.
331 //=================================================================
332 template<class ELEMENT>
333 class AlgebraicChannelWithLeafletMesh : public AlgebraicMesh,
334 public virtual ChannelWithLeafletMesh<ELEMENT>
335 {
336  public:
337 
338  ///\short Constructor: Pass pointer to GeomObject that represents the leaflet,
339  /// the length of the domain to left and right of the leaflet, the
340  /// height of the leaflet and the overall height of the channel,
341  /// the number of element columns to the left and right of the leaflet,
342  /// the number of rows of elements from the bottom of the channel to
343  /// the end of the leaflet, the number of rows of elements above the
344  /// end of the leaflet. Timestepper defaults to Steady default
345  /// Timestepper defined in the Mesh base class
346  AlgebraicChannelWithLeafletMesh(GeomObject* leaflet_pt, const double& lleft,
347  const double& lright, const double& hleaflet,
348  const double& htot,
349  const unsigned& nleft, const unsigned& nright,
350  const unsigned& ny1, const unsigned& ny2,
351  TimeStepper* time_stepper_pt=
352  &Mesh::Default_TimeStepper) :
353  ChannelWithLeafletMesh<ELEMENT>(leaflet_pt,lleft,lright,hleaflet,htot,
354  nleft,nright,ny1,ny2,
355  time_stepper_pt)
356  {
357  // Store origin of leaflet for fast reference
358  Vector<double> zeta(1);
359  zeta[0]=0.0;
360  Vector<double> r(2);
361  this->Leaflet_pt->position(zeta,r);
362  X_0 = r[0];
363 
364  // Store length of the leaflet for fast access (it's also available
365  // through the domain, of course)
366  Hleaflet = hleaflet;
367 
368  // Add the geometric object to the list associated with this AlgebraicMesh
369  AlgebraicMesh::add_geom_object_list_pt(leaflet_pt);
370 
371  //Setup algebraic node update operations
372  setup_algebraic_node_update();
373  }
374 
375 
376  /// \short Destructor: empty
378 
379 
380  /// \short Update the geometric references that are used
381  /// to update node after mesh adaptation.
382  /// Empty -- no update of node update required without adaptivity
383  void update_node_update(AlgebraicNode*& node_pt) {}
384 
385  /// \short Update nodal position at time level t (t=0: present;
386  /// t>0: previous)
387  void algebraic_node_update(const unsigned& t, AlgebraicNode*& node_pt);
388 
389 protected:
390 
391  /// Function to setup the algebraic node update
392  void setup_algebraic_node_update();
393 
394  /// Update function for nodes in lower left region (I)
395  void node_update_I(const unsigned& t, AlgebraicNode*& node_pt);
396 
397  /// Update function for nodes in lower right region (II)
398  void node_update_II(const unsigned& t, AlgebraicNode*& node_pt);
399 
400  /// Update function for nodes in upper left region (III)
401  void node_update_III(const unsigned& t, AlgebraicNode*& node_pt);
402 
403  /// Update function for nodes in upper right region (IV)
404  void node_update_IV(const unsigned& t,AlgebraicNode*& node_pt);
405 
406  /// Helper function
407  void slanted_bound_up(const unsigned& t,const Vector<double>& zeta,
408  Vector<double>& r);
409 
410  /// Origin of the wall (stored explicitly for reference in
411  /// algebraic node update -- it's also stored independently in
412  /// domain....)
413  double X_0;
414 
415  /// Length of the leaflet (stored explicitly for reference in
416  /// algebraic node update -- it's also stored independently in
417  /// domain....)
418  double Hleaflet;
419 
420 };
421 
422 ///////////////////////////////////////////////////////////////////////////
423 ///////////////////////////////////////////////////////////////////////////
424 ///////////////////////////////////////////////////////////////////////////
425 
426 
427 
428 //===================================================================
429 /// Refineable version of algebraic ChannelWithLeafletMesh
430 //===================================================================
431 template<class ELEMENT>
433 public RefineableQuadMesh<ELEMENT>,
434  public virtual AlgebraicChannelWithLeafletMesh<ELEMENT>
435 {
436 
437 public:
438 
439  ///\short Constructor: Pass pointer to GeomObject that represents the leaflet,
440  /// the length of the domain to left and right of the leaflet, the
441  /// height of the leaflet and the overall height of the channel,
442  /// the number of element columns to the left and right of the leaflet,
443  /// the number of rows of elements from the bottom of the channel to
444  /// the end of the leaflet, the number of rows of elements above the
445  /// end of the leaflet. Timestepper defaults to Steady default
446  /// Timestepper defined in the Mesh base class
448  GeomObject* leaflet_pt,
449  const double& lleft,
450  const double& lright,
451  const double& hleaflet,
452  const double& htot,
453  const unsigned& nleft, const unsigned& nright,
454  const unsigned& ny1, const unsigned& ny2,
455  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper) :
456  ChannelWithLeafletMesh<ELEMENT>(leaflet_pt,lleft,lright,hleaflet,htot,
457  nleft,nright,ny1,ny2,
458  time_stepper_pt),
459  AlgebraicChannelWithLeafletMesh<ELEMENT>(leaflet_pt,lleft,lright,hleaflet,
460  htot,nleft,nright,ny1,ny2,
461  time_stepper_pt)
462  {
463  // Build quadtree forest
464  this->setup_quadtree_forest();
465  }
466 
467  /// \short Update the node update data for specified node following
468  /// any mesh adapation
469  void update_node_update(AlgebraicNode*& node_pt);
470 
471 };
472 
473 
474 /////////////////////////////////////////////////////////////////////
475 /////////////////////////////////////////////////////////////////////
476 /////////////////////////////////////////////////////////////////////
477 
478 
479 //==========================================================================
480 /// Channel with leaflet mesh upgraded to (pseudo-)solid mesh
481 //==========================================================================
482 template <class ELEMENT>
484  public virtual ChannelWithLeafletMesh<ELEMENT>, public virtual SolidMesh
485 {
486 
487 public:
488 
489  ///\short Constructor: Pass pointer to GeomObject that represents the
490  /// leaflet, the length of the domain to left and right of the leaflet, the
491  /// height of the leaflet and the overall height of the channel,
492  /// the number of element columns to the left and right of the leaflet,
493  /// the number of rows of elements from the bottom of the channel to
494  /// the end of the leaflet, the number of rows of elements above the
495  /// end of the leaflet. Timestepper defaults to Steady default
496  /// Timestepper defined in the Mesh base class
497  PseudoElasticChannelWithLeafletMesh(GeomObject* leaflet_pt,
498  const double& lleft,
499  const double& lright,
500  const double& hleaflet,
501  const double& htot,
502  const unsigned& nleft,
503  const unsigned& nright,
504  const unsigned& ny1,
505  const unsigned& ny2,
506  TimeStepper* time_stepper_pt=
507  &Mesh::Default_TimeStepper) :
508  ChannelWithLeafletMesh<ELEMENT>(leaflet_pt,lleft,lright,hleaflet,htot,
509  nleft,nright,ny1,ny2,
510  time_stepper_pt)
511  {
512  // Update position of all nodes (the ones haven't been given
513  // positions yet!)
514  bool update_all_solid_nodes=true;
515  node_update(update_all_solid_nodes);
516 
517  // Make the current configuration the undeformed one by
518  // setting the nodal Lagrangian coordinates to their current
519  // Eulerian ones
520  set_lagrangian_nodal_coordinates();
521  }
522 
523  /// Destructor : empty
525 
526 };
527 
528 
529 }
530 
531 #endif
double X_0
Orientation (x-coordinate of step plane)
Channel with leaflet mesh upgraded to (pseudo-)solid mesh.
ChannelWithLeafletDomain * domain_pt()
Access function to domain.
Refineable version of ChannelWithLeafletMesh.
MacroElementNodeUpdateChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...
RefineableChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...
GeomObject * Leaflet_pt
Pointer to GeomObject that represents the leaflet.
virtual ~ChannelWithLeafletMesh()
Destructor : empty.
PseudoElasticChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...
void update_node_update(AlgebraicNode *&node_pt)
Update the geometric references that are used to update node after mesh adaptation. Empty – no update of node update required without adaptivity.
ChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...
Refineable version of algebraic ChannelWithLeafletMesh.
ChannelWithLeafletDomain * Domain_pt
Pointer to domain.
AlgebraicChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...
RefineableAlgebraicChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...
MacroElementNodeUpdateRefineableChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...