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