quarter_tube_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-2023 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 #ifndef OOMPH_QUARTER_TUBE_MESH_HEADER
27 #define OOMPH_QUARTER_TUBE_MESH_HEADER
28 
29 // Headers
30 #include "../generic/refineable_brick_mesh.h"
31 #include "../generic/macro_element.h"
32 #include "../generic/domain.h"
33 #include "../generic/algebraic_elements.h"
34 #include "../generic/brick_mesh.h"
35 #include "../generic/macro_element_node_update_element.h"
36 
37 
38 // Include the headers file for domain
39 #include "quarter_tube_domain.h"
40 
41 namespace oomph
42 {
43  //====================================================================
44  /// 3D quarter tube mesh class.
45  /// The domain is specified by the GeomObject that identifies
46  /// boundary 3. Non-refineable base version!
47  ///
48  /// The mesh boundaries are numbered as follows:
49  /// - Boundary 0: "Inflow" cross section; located along the
50  /// line parametrised by \f$ \xi_0 = \xi_0^{lo} \f$
51  /// on the geometric object that specifies the wall.
52  /// - Boundary 1: Plane x=0
53  /// - Boundary 2: Plane y=0
54  /// - Boundary 3: The curved wall
55  /// - Boundary 4: "Outflow" cross section; located along the
56  /// line parametrised by \f$ \xi_0 = \xi_0^{hi} \f$
57  /// on the geometric object that specifies the wall.
58  ///
59  /// IMPORTANT NOTE: The interface looks more general than it should.
60  /// The toplogy must remain that of a quarter tube,
61  /// or the mesh generation will break.
62  //====================================================================
63  template<class ELEMENT>
64  class QuarterTubeMesh : public virtual BrickMeshBase
65  {
66  public:
67  /// Constructor: Pass pointer to geometric object that
68  /// specifies the wall, start and end coordinates on the
69  /// geometric object, and the fraction along
70  /// which the dividing line is to be placed, and the timestepper.
71  /// Timestepper defaults to Steady dummy timestepper.
72  QuarterTubeMesh(GeomObject* wall_pt,
73  const Vector<double>& xi_lo,
74  const double& fract_mid,
75  const Vector<double>& xi_hi,
76  const unsigned& nlayer,
77  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper);
78 
79  /// Destructor: empty
80  virtual ~QuarterTubeMesh()
81  {
82  delete Domain_pt;
83  }
84 
85  /// Access function to GeomObject representing wall
86  GeomObject*& wall_pt()
87  {
88  return Wall_pt;
89  }
90 
91  /// Access function to domain
93  {
94  return Domain_pt;
95  }
96 
97  /// Function pointer for function that squashes
98  /// the outer macro elements towards
99  /// the wall by mapping the input value of the "radial" macro element
100  /// coordinate to the return value (defined in the underlying Domain object)
102  {
103  return Domain_pt->bl_squash_fct_pt();
104  }
105 
106 
107  /// Function pointer for function for axial spacing
109  {
111  }
112 
113  /// Access function to underlying domain
115  {
116  return Domain_pt;
117  }
118 
119  protected:
120  /// Pointer to domain
122 
123  /// Pointer to the geometric object that represents the curved wall
124  GeomObject* Wall_pt;
125 
126  /// Lower limits for the coordinates along the wall
127  Vector<double> Xi_lo;
128 
129  /// Fraction along wall where outer ring is to be divided
130  double Fract_mid;
131 
132  /// Upper limits for the coordinates along the wall
133  Vector<double> Xi_hi;
134  };
135 
136 
137  /// /////////////////////////////////////////////////////////////////
138  /// /////////////////////////////////////////////////////////////////
139  /// /////////////////////////////////////////////////////////////////
140 
141 
142  //=============================================================
143  /// Adaptative version of the QuarterTubeMesh base mesh.
144  /// The domain is specified by the GeomObject that identifies
145  /// boundary 3.
146  ///
147  /// The mesh boundaries are numbered as follows:
148  /// - Boundary 0: "Inflow" cross section; located along the
149  /// line parametrised by \f$ \xi_0 = \xi_0^{lo} \f$
150  /// on the geometric object that specifies the wall.
151  /// - Boundary 1: Plane x=0
152  /// - Boundary 2: Plane y=0
153  /// - Boundary 3: The curved wall
154  /// - Boundary 4: "Outflow" cross section; located along the
155  /// line parametrised by \f$ \xi_0 = \xi_0^{hi} \f$
156  /// on the geometric object that specifies the wall.
157  //=============================================================
158  template<class ELEMENT>
159  class RefineableQuarterTubeMesh : public virtual QuarterTubeMesh<ELEMENT>,
160  public RefineableBrickMesh<ELEMENT>
161 
162  {
163  public:
164  /// Constructor for adaptive deformable quarter tube mesh class.
165  /// The domain is specified by the GeomObject that
166  /// identifies boundary 3. Pass pointer to geometric object that
167  /// specifies the wall, start and end coordinates on the
168  /// geometric object, and the fraction along
169  /// which the dividing line is to be placed, and the timestepper.
170  /// Timestepper defaults to Steady dummy timestepper.
172  GeomObject* wall_pt,
173  const Vector<double>& xi_lo,
174  const double& fract_mid,
175  const Vector<double>& xi_hi,
176  const unsigned& nlayer,
177  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
178  : QuarterTubeMesh<ELEMENT>(
179  wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt)
180  {
181  // Loop over all elements and set macro element pointer
182  for (unsigned ielem = 0; ielem < QuarterTubeMesh<ELEMENT>::nelement();
183  ielem++)
184  {
185  dynamic_cast<RefineableQElement<3>*>(
187  ->set_macro_elem_pt(this->Domain_pt->macro_element_pt(ielem));
188  }
189 
190 
191  // Setup Octree forest: Turn elements into individual octrees
192  // and plant in forest
193  Vector<TreeRoot*> trees_pt;
194  for (unsigned iel = 0; iel < QuarterTubeMesh<ELEMENT>::nelement(); iel++)
195  {
196  FiniteElement* el_pt = QuarterTubeMesh<ELEMENT>::finite_element_pt(iel);
197  ELEMENT* ref_el_pt = dynamic_cast<ELEMENT*>(el_pt);
198  OcTreeRoot* octree_root_pt = new OcTreeRoot(ref_el_pt);
199  trees_pt.push_back(octree_root_pt);
200  }
201  this->Forest_pt = new OcTreeForest(trees_pt);
202 
203 #ifdef PARANOID
204  // Run self test
205  unsigned success_flag =
206  dynamic_cast<OcTreeForest*>(this->Forest_pt)->self_test();
207  if (success_flag == 0)
208  {
209  oomph_info << "Successfully built octree forest " << std::endl;
210  }
211  else
212  {
213  throw OomphLibError("Trouble in building octree forest ",
214  OOMPH_CURRENT_FUNCTION,
215  OOMPH_EXCEPTION_LOCATION);
216  }
217 #endif
218  }
219 
220  /// Destructor: empty
222  };
223 
224 
225  /// /////////////////////////////////////////////////////////////////
226  /// /////////////////////////////////////////////////////////////////
227  // MacroElementNodeUpdate-version of RefineableQuarterTubeMesh
228  /// /////////////////////////////////////////////////////////////////
229  /// /////////////////////////////////////////////////////////////////
230 
231  class MacroElementNodeUpdateNode;
232 
233  //========================================================================
234  /// MacroElementNodeUpdate version of RefineableQuarterTubeMesh
235  //========================================================================
236  template<class ELEMENT>
238  : public virtual MacroElementNodeUpdateMesh,
239  public virtual RefineableQuarterTubeMesh<ELEMENT>
240  {
241  public:
242  /// Constructor: Pass pointer to geometric object, start and
243  /// end coordinates on the geometric object and the fraction along
244  /// which the dividing line is to be placed when updating the nodal
245  /// positions, and timestepper (defaults to (Steady) default timestepper
246  /// defined in Mesh). Setup the refineable mesh (by calling the
247  /// constructor for the underlying RefineableQuarterTubeMesh)
248  /// and the algebraic node update functions for nodes.
250  GeomObject* wall_pt,
251  const Vector<double>& xi_lo,
252  const double& fract_mid,
253  const Vector<double>& xi_hi,
254  const unsigned& nlayer,
255  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
256  : MacroElementNodeUpdateMesh(),
257  RefineableQuarterTubeMesh<ELEMENT>(
258  wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt),
259  QuarterTubeMesh<ELEMENT>(
260  wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt)
261  {
262 #ifdef PARANOID
263  ELEMENT* el_pt = new ELEMENT;
264  if (dynamic_cast<MacroElementNodeUpdateElementBase*>(el_pt) == 0)
265  {
266  std::ostringstream error_message;
267  error_message << "Base class for ELEMENT in "
268  << "MacroElementNodeUpdateRefineableQuarterTubeMesh needs"
269  << "to be of type MacroElementNodeUpdateElement!\n";
270  error_message << "Whereas it is: typeid(el_pt).name()"
271  << typeid(el_pt).name() << std::endl;
272 
273  std::string function_name =
274  "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
275  function_name +=
276  "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh()";
277 
278  throw OomphLibError(error_message.str(),
279  OOMPH_CURRENT_FUNCTION,
280  OOMPH_EXCEPTION_LOCATION);
281  }
282  delete el_pt;
283 #endif
284 
285  // Setup all the information that's required for MacroElement-based
286  // node update: Tell the elements that their geometry depends on the
287  // fishback geometric object
289  }
290 
291  /// Destructor: empty
293 
294  /// Resolve mesh update: Update current nodal
295  /// positions via sparse MacroElement-based update.
296  /// [Doesn't make sense to use this mesh with SolidElements anyway,
297  /// so we buffer the case if update_all_solid_nodes is set to
298  /// true.]
299  void node_update(const bool& update_all_solid_nodes = false)
300  {
301 #ifdef PARANOID
302  if (update_all_solid_nodes)
303  {
304  std::string error_message =
305  "Doesn't make sense to use an MacroElementNodeUpdateMesh with\n";
306  error_message +=
307  "SolidElements so specifying update_all_solid_nodes=true\n";
308  error_message += "doesn't make sense either\n";
309 
310  std::string function_name =
311  "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
312  function_name += "node_update()";
313 
314  throw OomphLibError(
315  error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
316  }
317 #endif
318  MacroElementNodeUpdateMesh::node_update();
319  }
320 
321  private:
322  /// Setup all the information that's required for MacroElement-based
323  /// node update: Tell the elements that their geometry depends on the
324  /// geometric object that parametrises the wall
326  {
327  unsigned n_element = this->nelement();
328  for (unsigned i = 0; i < n_element; i++)
329  {
330  // Upcast from FiniteElement to the present element
331  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(i));
332 
333 #ifdef PARANOID
334  // Check if cast is successful
335  MacroElementNodeUpdateElementBase* m_el_pt =
336  dynamic_cast<MacroElementNodeUpdateElementBase*>(el_pt);
337  if (m_el_pt == 0)
338  {
339  std::ostringstream error_message;
340  error_message
341  << "Failed to upcast to MacroElementNodeUpdateElementBase\n";
342  error_message << "Element must be derived from "
343  "MacroElementNodeUpdateElementBase\n";
344  error_message << "but it is of type " << typeid(el_pt).name();
345 
346  std::string function_name =
347  "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
348  function_name += "setup_macro_element_node_update()";
349 
350  throw OomphLibError(error_message.str(),
351  OOMPH_CURRENT_FUNCTION,
352  OOMPH_EXCEPTION_LOCATION);
353  }
354 #endif
355  // There's just one GeomObject
356  Vector<GeomObject*> geom_object_pt(1);
357  geom_object_pt[0] = this->Wall_pt;
358 
359  // Tell the element which geom objects its macro-element-based
360  // node update depends on
361  el_pt->set_node_update_info(geom_object_pt);
362  }
363 
364  // Add the geometric object(s) for the wall to the mesh's storage
365  Vector<GeomObject*> geom_object_pt(1);
366  geom_object_pt[0] = this->Wall_pt;
367  MacroElementNodeUpdateMesh::set_geom_object_vector_pt(geom_object_pt);
368 
369  // Fill in the domain pointer to the mesh's storage in the base class
370  MacroElementNodeUpdateMesh::macro_domain_pt() = this->domain_pt();
371  }
372  };
373 
374 
375  //======================================================================
376  /// AlgebraicMesh version of RefineableQuarterTubeMesh
377  //=====================================================================
378 
379 
380  //====================================================================
381  /// Algebraic 3D quarter tube mesh class.
382  ///
383  /// The mesh boundaries are numbered as follows:
384  /// - Boundary 0: "Inflow" cross section; located along the
385  /// line parametrised by \f$ \xi_0 = \xi_0^{lo} \f$
386  /// on the geometric object that specifies the wall.
387  /// - Boundary 1: Plane x=0
388  /// - Boundary 2: Plane y=0
389  /// - Boundary 3: The curved wall - specified by the GeomObject
390  /// passed to the mesh constructor.
391  /// - Boundary 4: "Outflow" cross section; located along the
392  /// line parametrised by \f$ \xi_0 = \xi_0^{hi} \f$
393  /// on the geometric object that specifies the wall.
394  //====================================================================
395 
396 
397  //========================================================================
398  /// Algebraic version of RefineableQuarterTubeMesh
399  ///
400  /// Cross section through mesh looking along tube.........
401  ///
402  /// ---___
403  /// | ---____
404  /// | - BOUNDARY 3
405  /// | /
406  /// | [Region 2] / |
407  /// | / |
408  /// | N / |
409  /// | |_ E / |
410  /// BOUNDARY 1 |------------ |
411  /// | | |
412  /// | [Region 0] | [Region 1] | ^
413  /// | | | / \ direction of
414  /// | N | N | | 2nd Lagrangian
415  /// | |_ E | |_ E | | coordinate
416  /// |____________|____________| | along wall GeomObject
417  ///
418  /// BOUNDARY 2
419  ///
420  /// The Domain is built of slices each consisting of three
421  /// MacroElements as sketched.
422  /// The local coordinates are such that the (E)astern direction
423  /// coincides with the positive s_0 direction, while the
424  /// (N)orther direction coincides with the positive s_1 direction.
425  /// The positive s_2 direction points down the tube.
426  ///
427  /// Elements need to be derived from AlgebraicElementBase. In
428  /// addition to the refinement procedures available for the
429  /// RefineableQuarterTubeMesh which forms the basis for this mesh,
430  /// three algebraic node update functions are implemented for the nodes
431  /// in the three regions defined by the Domain MacroElements.
432  /// Note: it is assumed the cross section down the tube is
433  /// uniform when setup_algebraic_node_update() is called.
434  //========================================================================
435  template<class ELEMENT>
437  : public virtual AlgebraicMesh,
438  public RefineableQuarterTubeMesh<ELEMENT>
439  {
440  public:
441  /// Constructor: Pass pointer to geometric object, start and
442  /// end coordinates of the geometric object and the fraction along
443  /// the 2nd Lagrangian coordinate at which the dividing line between
444  /// region 1 and region 2 is to be placed, and timestepper
445  /// (defaults to (Steady) default timestepper defined in Mesh).
446  /// Sets up the refineable mesh (by calling the constructor for the
447  /// underlying RefineableQuarterTubeMesh).
449  GeomObject* wall_pt,
450  const Vector<double>& xi_lo,
451  const double& fract_mid,
452  const Vector<double>& xi_hi,
453  const unsigned& nlayer,
454  const double centre_box_size = 1.0,
455  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
456  : QuarterTubeMesh<ELEMENT>(
457  wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt),
458  RefineableQuarterTubeMesh<ELEMENT>(
459  wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt),
460  Centre_box_size(centre_box_size)
461  {
462 #ifdef PARANOID
463  ELEMENT* el_pt = new ELEMENT;
464  if (dynamic_cast<AlgebraicElementBase*>(el_pt) == 0)
465  {
466  std::ostringstream error_message;
467 
468  error_message << "Base class for ELEMENT in "
469  << "AlgebraicRefineableQuarterTubeMesh needs"
470  << "to be of type AlgebraicElement!\n";
471  error_message << "Whereas it is: typeid(el_pt).name()"
472  << typeid(el_pt).name() << std::endl;
473 
474  std::string function_name = " AlgebraicRefineableQuarterTubeMesh::\n";
475  function_name += "AlgebraicRefineableQuarterTubeMesh()";
476 
477  throw OomphLibError(error_message.str(),
478  OOMPH_CURRENT_FUNCTION,
479  OOMPH_EXCEPTION_LOCATION);
480  }
481  delete el_pt;
482 #endif
483 
484  // Add the geometric object to the list associated with this AlgebraicMesh
485  AlgebraicMesh::add_geom_object_list_pt(wall_pt);
486 
487  // Setup algebraic node update operations
489 
490  // Ensure nodes are in their default position
491  node_update();
492  }
493 
494  /// Run self-test for algebraic mesh -- return 0/1 for OK/failure
495  unsigned self_test()
496  {
497  return AlgebraicMesh::self_test();
498  }
499 
500  /// Broken version of the QuarterTubeDomain function
501  /// Function is broken because axial spacing isn't implemented
502  /// yet for the Algebraic version of the RefineableQuarterTubeMesh.
503  /// Note: this function must be used BEFORE algebraic_node_update(...)
504  /// is called.
506  {
507  std::ostringstream error_message;
508  error_message << "AxialSpacingFctPt has not been implemented "
509  << "for the AlgebraicRefineableQuarterTubeMesh\n";
510 
511  std::string function_name =
512  " AlgebraicRefineableQuarterTubeMesh::AxialSpacingFctPt()";
513 
514  throw OomphLibError(
515  error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
516 
517  return this->Domain_pt->axial_spacing_fct_pt();
518  }
519 
520  /// Resolve mesh update: Update current nodal
521  /// positions via algebraic node update.
522  /// [Doesn't make sense to use this mesh with SolidElements anyway,
523  /// so we buffer the case if update_all_solid_nodes is set to
524  /// true.]
525  void node_update(const bool& update_all_solid_nodes = false)
526  {
527 #ifdef PARANOID
528  if (update_all_solid_nodes)
529  {
530  std::string error_message =
531  "Doesn't make sense to use an AlgebraicMesh with\n";
532  error_message +=
533  "SolidElements so specifying update_all_solid_nodes=true\n";
534  error_message += "doesn't make sense either\n";
535 
536  std::string function_name = " AlgebraicRefineableQuarterTubeMesh::";
537  function_name += "node_update()";
538 
539  throw OomphLibError(
540  error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
541  }
542 #endif
543 
544  AlgebraicMesh::node_update();
545  }
546 
547 
548  /// Implement the algebraic node update function for a node
549  /// at time level t (t=0: present; t>0: previous): Update with
550  /// the node's first (default) update function.
551  void algebraic_node_update(const unsigned& t, AlgebraicNode*& node_pt)
552  {
553  // Update with the update function for the node's first (default)
554  // node update fct
555  unsigned id = node_pt->node_update_fct_id();
556 
557  switch (id)
558  {
559  case Central_region:
560 
561  // Central region
562  node_update_central_region(t, node_pt);
563  break;
564 
565  case Lower_right_region:
566 
567  // Lower right region
568  node_update_lower_right_region(t, node_pt);
569  break;
570 
571  case Upper_left_region:
572 
573  // Upper left region
574  node_update_upper_left_region(t, node_pt);
575  break;
576 
577  default:
578 
579  std::ostringstream error_message;
580  error_message << "The node update fct id is " << id
581  << ", but it should only be one of " << Central_region
582  << ", " << Lower_right_region << " or "
583  << Upper_left_region << std::endl;
584  std::string function_name = " AlgebraicRefineableQuarterTubeMesh::";
585  function_name += "algebraic_node_update()";
586 
587  throw OomphLibError(error_message.str(),
588  OOMPH_CURRENT_FUNCTION,
589  OOMPH_EXCEPTION_LOCATION);
590  }
591  }
592 
593  /// Update the node update info for specified algebraic node
594  /// following any spatial mesh adaptation.
595  void update_node_update(AlgebraicNode*& node_pt)
596  {
597  // Get all node update fct for this node (resizes internally)
598  Vector<int> id;
599  node_pt->node_update_fct_id(id);
600 
601  // Loop over all update fcts
602  unsigned n_update = id.size();
603  for (unsigned i = 0; i < n_update; i++)
604  {
605  update_node_update_in_region(node_pt, id[i]);
606  }
607  }
608 
609  private:
610  /// Size of centre box
612 
613  /// Remesh function ids
614  enum
615  {
619  };
620 
621  /// Fractional width of central region
622  double Lambda_x;
623 
624  /// Fractional height of central region
625  double Lambda_y;
626 
627  /// Algebraic update function for a node that is located
628  /// in the central region
629  void node_update_central_region(const unsigned& t, AlgebraicNode*& node_pt);
630 
631  /// Algebraic update function for a node that is located
632  /// in the lower-right region
633  void node_update_lower_right_region(const unsigned& t,
634  AlgebraicNode*& node_pt);
635 
636  /// Algebraic update function for a node that is located
637  /// in the upper-left region
638  void node_update_upper_left_region(const unsigned& t,
639  AlgebraicNode*& node_pt);
640 
641  /// Setup algebraic update operation for all nodes
643 
644  /// Update algebraic node update function for nodes in
645  /// the region defined by region_id
646  void update_node_update_in_region(AlgebraicNode*& node_pt, int& region_id);
647  };
648 
649 
650 } // namespace oomph
651 #endif
AlgebraicMesh version of RefineableQuarterTubeMesh.
void node_update_central_region(const unsigned &t, AlgebraicNode *&node_pt)
Algebraic update function for a node that is located in the central region.
unsigned self_test()
Run self-test for algebraic mesh – return 0/1 for OK/failure.
void setup_algebraic_node_update()
Setup algebraic update operation for all nodes.
void node_update_lower_right_region(const unsigned &t, AlgebraicNode *&node_pt)
Algebraic update function for a node that is located in the lower-right region.
double Lambda_x
Fractional width of central region.
void update_node_update(AlgebraicNode *&node_pt)
Update the node update info for specified algebraic node following any spatial mesh adaptation.
double Lambda_y
Fractional height of central region.
QuarterTubeDomain::AxialSpacingFctPt & axial_spacing_fct_pt()
Broken version of the QuarterTubeDomain function Function is broken because axial spacing isn't imple...
void node_update_upper_left_region(const unsigned &t, AlgebraicNode *&node_pt)
Algebraic update function for a node that is located in the upper-left region.
AlgebraicRefineableQuarterTubeMesh(GeomObject *wall_pt, const Vector< double > &xi_lo, const double &fract_mid, const Vector< double > &xi_hi, const unsigned &nlayer, const double centre_box_size=1.0, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object, start and end coordinates of the geometric object and ...
void update_node_update_in_region(AlgebraicNode *&node_pt, int &region_id)
Update algebraic node update function for nodes in the region defined by region_id.
void node_update(const bool &update_all_solid_nodes=false)
Resolve mesh update: Update current nodal positions via algebraic node update. [Doesn't make sense to...
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Implement the algebraic node update function for a node at time level t (t=0: present; t>0: previous)...
MacroElementNodeUpdate version of RefineableQuarterTubeMesh.
MacroElementNodeUpdateRefineableQuarterTubeMesh(GeomObject *wall_pt, const Vector< double > &xi_lo, const double &fract_mid, const Vector< double > &xi_hi, const unsigned &nlayer, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object, start and end coordinates on the geometric object and ...
void node_update(const bool &update_all_solid_nodes=false)
Resolve mesh update: Update current nodal positions via sparse MacroElement-based update....
void setup_macro_element_node_update()
Setup all the information that's required for MacroElement-based node update: Tell the elements that ...
Quarter tube as domain. Domain is bounded by curved boundary which is represented by a GeomObject....
AxialSpacingFctPt & axial_spacing_fct_pt()
Function pointer for function that implements axial spacing of macro elements.
BLSquashFctPt & bl_squash_fct_pt()
Function pointer for function that squashes the outer two macro elements towards the wall by mapping ...
double(* BLSquashFctPt)(const double &s)
Typedef for function pointer for function that squashes the outer two macro elements towards the wall...
double(* AxialSpacingFctPt)(const double &xi)
Typedef for function pointer for function that implements axial spacing of macro elements.
3D quarter tube mesh class. The domain is specified by the GeomObject that identifies boundary 3....
QuarterTubeDomain * Domain_pt
Pointer to domain.
Vector< double > Xi_lo
Lower limits for the coordinates along the wall.
QuarterTubeDomain * domain_pt() const
Access function to underlying domain.
QuarterTubeMesh(GeomObject *wall_pt, const Vector< double > &xi_lo, const double &fract_mid, const Vector< double > &xi_hi, const unsigned &nlayer, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object that specifies the wall, start and end coordinates on t...
QuarterTubeDomain * domain_pt()
Access function to domain.
virtual QuarterTubeDomain::AxialSpacingFctPt & axial_spacing_fct_pt()
Function pointer for function for axial spacing.
GeomObject * Wall_pt
Pointer to the geometric object that represents the curved wall.
Vector< double > Xi_hi
Upper limits for the coordinates along the wall.
double Fract_mid
Fraction along wall where outer ring is to be divided.
virtual ~QuarterTubeMesh()
Destructor: empty.
GeomObject *& wall_pt()
Access function to GeomObject representing wall.
QuarterTubeDomain::BLSquashFctPt & bl_squash_fct_pt()
Function pointer for function that squashes the outer macro elements towards the wall by mapping the ...
///////////////////////////////////////////////////////////////// ///////////////////////////////////...
virtual ~RefineableQuarterTubeMesh()
Destructor: empty.
RefineableQuarterTubeMesh(GeomObject *wall_pt, const Vector< double > &xi_lo, const double &fract_mid, const Vector< double > &xi_hi, const unsigned &nlayer, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor for adaptive deformable quarter tube mesh class. The domain is specified by the GeomObjec...
////////////////////////////////////////////////////////////////////// //////////////////////////////...