fish_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_FISH_MESH_HEADER
27#define OOMPH_FISH_MESH_HEADER
28
29// Headers
32#include "generic/domain.h"
34#include "generic/quad_mesh.h"
36
37// Include algebraic elements
39
40// Include the macro element node update elements
42
43// Include the headers file for domain
44#include "fish_domain.h"
45
46namespace oomph
47{
48 //=================================================================
49 /// Fish shaped mesh. The geometry is defined by
50 /// the Domain object FishDomain.
51 //=================================================================
52 template<class ELEMENT>
53 class FishMesh : public virtual QuadMeshBase
54 {
55 public:
56 /// Constructor: Pass pointer to timestepper
57 /// (defaults to the (Steady) default timestepper defined in Mesh)
59
60 /// Constructor: Pass pointer GeomObject that defines
61 /// the fish's back and pointer to timestepper
62 /// (defaults to the (Steady) default timestepper defined in Mesh)
64 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper);
65
66 /// Destructor: Kill the geom object that represents the fish's back
67 /// (if necessary)
68 virtual ~FishMesh()
69 {
71 {
72 delete Back_pt;
73 Back_pt = 0;
74 }
75 }
76
77 /// Access function to geom object that represents the fish's back
79 {
80 return Back_pt;
81 }
82
83 /// Access function to FishDomain
85 {
86 return Domain_pt;
87 }
88
89 protected:
90 /// Remesh function ids
91 enum
92 {
97 };
98
99 /// Build the mesh, using the geometric object identified by Back_pt
100 void build_mesh(TimeStepper* time_stepper_pt);
101
102 /// Pointer to fish back
104
105 /// Pointer to domain
107
108 /// Do I need to kill the fish back geom object?
110 };
111
112
113 ///////////////////////////////////////////////////////////////////////
114 ///////////////////////////////////////////////////////////////////////
115 // Refineable fish-shaped mesh
116 ///////////////////////////////////////////////////////////////////////
117 ///////////////////////////////////////////////////////////////////////
118
119 //=================================================================
120 /// Refineable fish shaped mesh. The geometry is defined by
121 /// the Domain object FishDomain.
122 //=============================start_adaptive_fish_mesh============
123 template<class ELEMENT>
124 class RefineableFishMesh : public virtual FishMesh<ELEMENT>,
125 public RefineableQuadMesh<ELEMENT>
126 {
127 public:
128 /// Constructor: Pass pointer to timestepper -- defaults to (Steady)
129 /// default timestepper defined in the Mesh base class
131 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
132 : FishMesh<ELEMENT>(time_stepper_pt)
133 {
134 // Nodal positions etc. were created in constructor for
135 // FishMesh<...>. Only need to setup adaptive information.
136
137 // Do what it says....
139
140 } // end of constructor
141
142
143 /// Constructor: Pass pointer GeomObject that defines
144 /// the fish's back and pointer to timestepper
145 /// (defaults to (Steady) default timestepper defined in Mesh)
148 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
149 : FishMesh<ELEMENT>(back_pt, time_stepper_pt)
150 {
151 // Nodal positions etc. were created in constructor for
152 // FishMesh<...>. Only need to setup adaptive information.
153
154 // Do what it says....
156 }
157
158 /// Destructor: Empty -- all cleanup gets handled in the base
159 /// classes
161
162 protected:
163 /// Setup all the information that's required for spatial adaptivity:
164 /// Set pointers to macro elements and build quadtree forest.
165 /// (contained in separate function as this functionality is common
166 /// to both constructors),
167 void setup_adaptivity();
168
169 }; // end adaptive fish mesh
170
171
172 ////////////////////////////////////////////////////////////////////
173 ////////////////////////////////////////////////////////////////////
174 // MacroElementNodeUpdate-version of RefineableFishMesh
175 ////////////////////////////////////////////////////////////////////
176 ////////////////////////////////////////////////////////////////////
177
178 // Forward declaration
179 class MacroElementNodeUpdateNode;
180
181 //========================================================================
182 /// Refineable fish shaped mesh with MacroElement-based node update.
183 /// The fish's back is represented by a specified geometric object.
184 /// Some or all of the geometric Data in that geometric object
185 /// may contain unknowns in the global Problem. The dependency
186 /// on these unknowns is taken into account when setting up
187 /// the Jacobian matrix of the elements. For this purpose,
188 /// the element (whose type is specified by the template parameter)
189 /// must inherit from MacroElementNodeUpdateElementBase.
190 //========================================================================
191 template<class ELEMENT>
193 : public virtual MacroElementNodeUpdateMesh,
194 public virtual RefineableFishMesh<ELEMENT>
195 {
196 public:
197 /// Constructor: Pass pointer GeomObject that defines
198 /// the fish's back and pointer to timestepper
199 /// (defaults to (Steady) default timestepper defined in Mesh).
202 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
203 : FishMesh<ELEMENT>(back_pt, time_stepper_pt),
204 RefineableFishMesh<ELEMENT>(time_stepper_pt)
205 {
206#ifdef PARANOID
207 ELEMENT* el_pt = new ELEMENT;
208 if (dynamic_cast<MacroElementNodeUpdateElementBase*>(el_pt) == 0)
209 {
210 std::ostringstream error_message;
211 error_message << "Base class for ELEMENT in "
212 << "MacroElementNodeUpdateRefineableFishMesh needs"
213 << "to be of type MacroElementNodeUpdateElement!\n";
214 error_message << "Whereas it is: typeid(el_pt).name()"
215 << typeid(el_pt).name() << std::endl;
216
217 std::string function_name =
218 "MacroElementNodeUpdateRefineableFishMesh::\n";
219 function_name += "MacroElementNodeUpdateRefineableFishMesh()";
220
221 throw OomphLibError(error_message.str(),
224 }
225 delete el_pt;
226#endif
227
228 // Setup all the information that's required for MacroElement-based
229 // node update: Tell the elements that their geometry depends on the
230 // fishback geometric object
231 unsigned n_element = this->nelement();
232 for (unsigned i = 0; i < n_element; i++)
233 {
234 // Upcast from FiniteElement to the present element
235 ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(i));
236
237#ifdef PARANOID
238 // Check if cast is successful
241 if (m_el_pt == 0)
242 {
243 std::ostringstream error_message;
244 error_message
245 << "Failed to upcast to MacroElementNodeUpdateElementBase\n";
246 error_message << "Element must be derived from "
247 "MacroElementNodeUpdateElementBase\n";
248 error_message << "but it is of type " << typeid(el_pt).name();
249
250 std::string function_name =
251 "MacroElementNodeUpdateRefineableFishMesh::\n";
252 function_name += "MacroElementNodeUpdateRefinableFishMesh()";
253
254 throw OomphLibError(error_message.str(),
257 }
258#endif
259 // There's just one GeomObject
260 Vector<GeomObject*> geom_object_pt(1);
261 geom_object_pt[0] = this->Back_pt;
262
263 // Tell the element which geom objects its macro-element-based
264 // node update depends on
265 el_pt->set_node_update_info(geom_object_pt);
266 }
267
268 // Add the geometric object(s) for the wall to the mesh's storage
269 Vector<GeomObject*> geom_object_pt(1);
270 geom_object_pt[0] = this->Back_pt;
272
273 // Fill in the domain pointer to the mesh's storage in the base class
275 }
276
277 /// Destructor: empty
279
280 /// Resolve mesh update: NodeUpdate current nodal
281 /// positions via sparse MacroElement-based update.
282 /// [Doesn't make sense to use this mesh with SolidElements anyway,
283 /// so we buffer the case if update_all_solid_nodes is set to
284 /// true.]
285 void node_update(const bool& update_all_solid_nodes = false)
286 {
287#ifdef PARANOID
289 {
290 std::string error_message =
291 "Doesn't make sense to use an MacroElementNodeUpdateMesh with\n";
292 error_message +=
293 "SolidElements so specifying update_all_solid_nodes=true\n";
294 error_message += "doesn't make sense either\n";
295
296 std::string function_name =
297 "MacroElementNodeUpdateRefineableFishMesh::";
298 function_name += "node_update()";
299
300 throw OomphLibError(
302 }
303#endif
305 }
306 };
307
308
309 ///////////////////////////////////////////////////////////////////////
310 ///////////////////////////////////////////////////////////////////////
311 // AlgebraicElement fish-shaped mesh
312 ///////////////////////////////////////////////////////////////////////
313 ///////////////////////////////////////////////////////////////////////
314
315 //=================================================================
316 /// Fish shaped mesh with algebraic node update function for nodes.
317 //=================================================================
318 template<class ELEMENT>
320 public virtual FishMesh<ELEMENT>
321 {
322 public:
323 /// Constructor: Pass pointer to timestepper.
324 /// (defaults to (Steady) default timestepper defined in Mesh)
326 : FishMesh<ELEMENT>(time_stepper_pt)
327 {
328 // Setup algebraic node update operations
330 }
331
332 /// Constructor: Pass pointer GeomObject that defines
333 /// the fish's back and pointer to timestepper
334 /// (defaults to (Steady) default timestepper defined in Mesh).
336 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
337 : FishMesh<ELEMENT>(back_pt, time_stepper_pt)
338 {
339 // Add the geometric object to the list associated with this AlgebraicMesh
341
342 // Setup algebraic node update operations
344 }
345
346 /// Destructor: empty
348
349 /// Update nodal position at time level t (t=0: present;
350 /// t>0: previous)
352 {
353 // Update with the update function for the node's first (default)
354 // node update fct
355 unsigned id = node_pt->node_update_fct_id();
356
357 // Upper/lower body
358 if ((id == this->Lower_body) || (id == this->Upper_body))
359 {
361 }
362 // Upper/lower fin
363 else if ((id == this->Lower_fin) || (id == this->Upper_fin))
364 {
366 }
367 else
368 {
369 std::ostringstream error_message;
370 error_message << "The node update fct id is " << id
371 << ", but it should only be one of " << this->Lower_body
372 << ", " << this->Upper_body << ", " << this->Lower_fin
373 << " or " << this->Upper_fin << std::endl;
374 std::string function_name =
375 "AlgebraicFishMesh::algebraic_node_update()";
376
377 throw OomphLibError(error_message.str(),
380 }
381 }
382
383 /// Resolve the node update function (we neither want the broken
384 /// empty one in the Mesh base class nor the macro-element-based one in the
385 /// RefineableQuadMesh base class but the AlgebraicElement one). [It doesn't
386 /// make sense to use this mesh with SolidElements so we buffer the case if
387 /// update_all_solid_nodes is set to true.]
388 virtual void node_update(const bool& update_all_solid_nodes = false)
389 {
390#ifdef PARANOID
392 {
393 std::string error_message =
394 "Doesn't make sense to use an AlgebraicMesh with\n";
395 error_message +=
396 "SolidElements so specifying update_all_solid_nodes=true\n";
397 error_message += "doesn't make sense either\n";
398
399 std::string function_name = "AlgebraicFishMesh::node_update()";
400
401 throw OomphLibError(
403 }
404#endif
406 }
407
408 /// Update the geometric references that are used
409 /// to update node after mesh adaptation.
410 /// We're assuming that the GeomObject that specifies
411 /// the fish back does not have sub-objects, therefore
412 /// no update is required -- all reference
413 /// values can simply be scaled. We simply
414 /// paranoid-check that this is actually the case,
415 /// by checking if locate_zeta() returns the
416 /// original data.
418 {
419#ifdef PARANOID
420
421 // Get the start and end Lagrangian coordinates on the
422 // wall from the domain:
423
424 /// Start coordinate on wall (near nose)
425 double xi_nose = this->Domain_pt->xi_nose();
426
427 /// End coordinate on wall (near tail)
428 double xi_tail = this->Domain_pt->xi_tail();
429
430 /// Check halfway along the object
432 zeta[0] = 0.5 * (xi_nose + xi_tail);
433
434 Vector<double> s(1);
436 this->Back_pt->locate_zeta(zeta, geom_obj_pt, s);
437
438 if ((geom_obj_pt != this->Back_pt) || (s[0] != zeta[0]))
439 {
440 std::ostringstream error_message;
441 error_message << "AlgebraicFishMesh only works with GeomObjects\n"
442 << "that do not contain sub-elements (e.g. GeomObjects\n"
443 << "that represent a wall finite element mesh!\n"
444 << "Back_pt : " << this->Back_pt << std::endl
445 << "geom_obj_pt: " << geom_obj_pt << std::endl
446 << "s[0] : " << s[0] << std::endl
447 << "zeta[0] : " << zeta[0] << std::endl;
448
449 throw OomphLibError(error_message.str(),
452 }
453#endif
454 }
455
456 protected:
457 /// Algebraic update function for nodes in upper/lower body
458 void node_update_in_body(const unsigned& t, AlgebraicNode*& node_pt);
459
460 /// Algebraic update function for nodes in upper/lower fin
461 void node_update_in_fin(const unsigned& t, AlgebraicNode*& node_pt);
462
463 /// Setup algebraic update operation for all nodes
464 /// (separate function because this task needs to be performed by
465 /// both constructors)
467 };
468
469
470 ///////////////////////////////////////////////////////////////////////
471 ///////////////////////////////////////////////////////////////////////
472 // Refineable algebraic element fish-shaped mesh
473 ///////////////////////////////////////////////////////////////////////
474 ///////////////////////////////////////////////////////////////////////
475
476 //=================================================================
477 /// Refineable fish shaped mesh with algebraic node update function.
478 //=================================================================
479 template<class ELEMENT>
481 public RefineableFishMesh<ELEMENT>
482 {
483 public:
484 /// Constructor: Pass pointer to timestepper.
485 /// (defaults to (Steady) default timestepper defined in Mesh)
486 // Note: FishMesh is virtual base and its constructor is automatically
487 // called first! --> this is where we need to build the mesh;
488 // the constructors of the derived meshes don't call the
489 // base constructor again and simply add the extra functionality.
491 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
492 : FishMesh<ELEMENT>(time_stepper_pt),
493 AlgebraicFishMesh<ELEMENT>(time_stepper_pt),
494 RefineableFishMesh<ELEMENT>(time_stepper_pt)
495 {
496 }
497
498
499 /// Constructor: Pass pointer GeomObject that defines
500 /// the fish's back and pointer to timestepper.
501 /// (defaults to (Steady) default timestepper defined in Mesh)
502 // Note: FishMesh is virtual base and its constructor is automatically
503 // called first! --> this is where we need to build the mesh;
504 // the constructors of the derived meshes don't call the
505 // base constructor again and simply add the extra functionality.
508 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
509 : FishMesh<ELEMENT>(back_pt, time_stepper_pt),
510 AlgebraicFishMesh<ELEMENT>(back_pt, time_stepper_pt),
511 RefineableFishMesh<ELEMENT>(back_pt, time_stepper_pt)
512 {
513 }
514
515
516 /// Destructor: empty
518
519 /// Resolve node update function: Use the one defined
520 /// in the AlgebraicFishMesh (where the bool flag is explained)
525 };
526
527} // namespace oomph
528
529#include "fish_mesh.template.cc"
530#endif
static char t char * s
Definition cfortran.h:568
cstr elem_len * i
Definition cfortran.h:603
char t
Definition cfortran.h:568
Fish shaped mesh with algebraic node update function for nodes.
Definition fish_mesh.h:321
virtual ~AlgebraicFishMesh()
Destructor: empty.
Definition fish_mesh.h:347
void setup_algebraic_node_update()
Setup algebraic update operation for all nodes (separate function because this task needs to be perfo...
virtual void node_update(const bool &update_all_solid_nodes=false)
Resolve the node update function (we neither want the broken empty one in the Mesh base class nor the...
Definition fish_mesh.h:388
AlgebraicFishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to timestepper. (defaults to (Steady) default timestepper defined in Mesh)
Definition fish_mesh.h:325
void node_update_in_body(const unsigned &t, AlgebraicNode *&node_pt)
Algebraic update function for nodes in upper/lower body.
void update_node_update(AlgebraicNode *&node_pt)
Update the geometric references that are used to update node after mesh adaptation....
Definition fish_mesh.h:417
AlgebraicFishMesh(GeomObject *back_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer GeomObject that defines the fish's back and pointer to timestepper (default...
Definition fish_mesh.h:335
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
Definition fish_mesh.h:351
void node_update_in_fin(const unsigned &t, AlgebraicNode *&node_pt)
Algebraic update function for nodes in upper/lower fin.
Algebraic meshes contain AlgebraicElements and AlgebraicNodes. They implement the node update functio...
void node_update(const bool &update_all_solid_nodes=false)
Update all nodal positions via algebraic node update functions [Doesn't make sense to use this mesh w...
void add_geom_object_list_pt(GeomObject *geom_object_pt)
Add the specified GeomObject to the list of geometric objects associated with this AlgebraicMesh; rem...
AlgebraicNode * node_pt(const unsigned long &n)
Return a pointer to the n-th global AlgebraicNode.
Algebraic nodes are nodes with an algebraic positional update function.
int node_update_fct_id()
Default (usually first if there are multiple ones) node update fct id.
Refineable fish shaped mesh with algebraic node update function.
Definition fish_mesh.h:482
AlgebraicRefineableFishMesh(GeomObject *back_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer GeomObject that defines the fish's back and pointer to timestepper....
Definition fish_mesh.h:506
virtual ~AlgebraicRefineableFishMesh()
Destructor: empty.
Definition fish_mesh.h:517
void node_update(const bool &update_all_solid_nodes=false)
Resolve node update function: Use the one defined in the AlgebraicFishMesh (where the bool flag is ex...
Definition fish_mesh.h:521
AlgebraicRefineableFishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to timestepper. (defaults to (Steady) default timestepper defined in Mesh)
Definition fish_mesh.h:490
Fish shaped domain, represented by four MacroElements. Shape is parametrised by GeomObject that repre...
Definition fish_domain.h:43
double & xi_nose()
Start coordinate on wall (near nose)
Definition fish_domain.h:99
double & xi_tail()
End coordinate on wall (near tail)
Fish shaped mesh. The geometry is defined by the Domain object FishDomain.
Definition fish_mesh.h:54
GeomObject * Back_pt
Pointer to fish back.
Definition fish_mesh.h:103
virtual ~FishMesh()
Destructor: Kill the geom object that represents the fish's back (if necessary)
Definition fish_mesh.h:68
FishDomain *& domain_pt()
Access function to FishDomain.
Definition fish_mesh.h:84
void build_mesh(TimeStepper *time_stepper_pt)
Build the mesh, using the geometric object identified by Back_pt.
GeomObject *& fish_back_pt()
Access function to geom object that represents the fish's back.
Definition fish_mesh.h:78
bool Must_kill_fish_back
Do I need to kill the fish back geom object?
Definition fish_mesh.h:109
FishDomain * Domain_pt
Pointer to domain.
Definition fish_mesh.h:106
A geometric object is an object that provides a parametrised description of its shape via the functio...
virtual void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
A geometric object may be composed of may sub-objects (e.g. a finite-element representation of a boun...
Base class for elements that allow MacroElement-based node update.
MacroElementNodeUpdateMeshes contain MacroElementNodeUpdateNodes which have their own node update fun...
void set_geom_object_vector_pt(Vector< GeomObject * > geom_object_vector_pt)
Set geometric objects associated with MacroElementNodeUpdateMesh; this must also be called from the c...
Domain *& macro_domain_pt()
Broken assignment operator.
void node_update(const bool &update_all_solid_nodes=false)
Update all nodal positions via sparse MacroElement-based update functions. If a Node is hanging its p...
Refineable fish shaped mesh with MacroElement-based node update. The fish's back is represented by a ...
Definition fish_mesh.h:195
void node_update(const bool &update_all_solid_nodes=false)
Resolve mesh update: NodeUpdate current nodal positions via sparse MacroElement-based update....
Definition fish_mesh.h:285
virtual ~MacroElementNodeUpdateRefineableFishMesh()
Destructor: empty.
Definition fish_mesh.h:278
MacroElementNodeUpdateRefineableFishMesh(GeomObject *back_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer GeomObject that defines the fish's back and pointer to timestepper (default...
Definition fish_mesh.h:200
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors.
Definition mesh.h:75
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition mesh.h:464
unsigned long nelement() const
Return number of elements in the mesh.
Definition mesh.h:598
An OomphLibError object which should be thrown when an run-time error is encountered....
Base class for quad meshes (meshes made of 2D quad elements).
Definition quad_mesh.h:57
Refineable fish shaped mesh. The geometry is defined by the Domain object FishDomain.
Definition fish_mesh.h:126
void setup_adaptivity()
Setup all the information that's required for spatial adaptivity: Set pointers to macro elements and ...
RefineableFishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to timestepper – defaults to (Steady) default timestepper defined in the Me...
Definition fish_mesh.h:130
RefineableFishMesh(GeomObject *back_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer GeomObject that defines the fish's back and pointer to timestepper (default...
Definition fish_mesh.h:146
virtual ~RefineableFishMesh()
Destructor: Empty – all cleanup gets handled in the base classes.
Definition fish_mesh.h:160
Intermediate mesh class that implements the mesh adaptation functions specified in the TreeBasedRefin...
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).