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