26 #ifndef OOMPH_QUARTER_TUBE_MESH_HEADER
27 #define OOMPH_QUARTER_TUBE_MESH_HEADER
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"
63 template<
class ELEMENT>
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);
158 template<
class ELEMENT>
160 public RefineableBrickMesh<ELEMENT>
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)
179 wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt)
182 for (
unsigned ielem = 0; ielem < QuarterTubeMesh<ELEMENT>::nelement();
185 dynamic_cast<RefineableQElement<3>*
>(
187 ->set_macro_elem_pt(this->
Domain_pt->macro_element_pt(ielem));
193 Vector<TreeRoot*> trees_pt;
194 for (
unsigned iel = 0; iel < QuarterTubeMesh<ELEMENT>::nelement(); 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);
201 this->Forest_pt =
new OcTreeForest(trees_pt);
205 unsigned success_flag =
206 dynamic_cast<OcTreeForest*
>(this->Forest_pt)->self_test();
207 if (success_flag == 0)
209 oomph_info <<
"Successfully built octree forest " << std::endl;
213 throw OomphLibError(
"Trouble in building octree forest ",
214 OOMPH_CURRENT_FUNCTION,
215 OOMPH_EXCEPTION_LOCATION);
231 class MacroElementNodeUpdateNode;
236 template<
class ELEMENT>
238 :
public virtual MacroElementNodeUpdateMesh,
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(),
258 wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt),
260 wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt)
263 ELEMENT* el_pt =
new ELEMENT;
264 if (
dynamic_cast<MacroElementNodeUpdateElementBase*
>(el_pt) == 0)
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;
273 std::string function_name =
274 "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
276 "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh()";
278 throw OomphLibError(error_message.str(),
279 OOMPH_CURRENT_FUNCTION,
280 OOMPH_EXCEPTION_LOCATION);
302 if (update_all_solid_nodes)
304 std::string error_message =
305 "Doesn't make sense to use an MacroElementNodeUpdateMesh with\n";
307 "SolidElements so specifying update_all_solid_nodes=true\n";
308 error_message +=
"doesn't make sense either\n";
310 std::string function_name =
311 "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
312 function_name +=
"node_update()";
315 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
318 MacroElementNodeUpdateMesh::node_update();
327 unsigned n_element = this->nelement();
328 for (
unsigned i = 0; i < n_element; i++)
331 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->element_pt(i));
335 MacroElementNodeUpdateElementBase* m_el_pt =
336 dynamic_cast<MacroElementNodeUpdateElementBase*
>(el_pt);
339 std::ostringstream 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();
346 std::string function_name =
347 "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
348 function_name +=
"setup_macro_element_node_update()";
350 throw OomphLibError(error_message.str(),
351 OOMPH_CURRENT_FUNCTION,
352 OOMPH_EXCEPTION_LOCATION);
356 Vector<GeomObject*> geom_object_pt(1);
357 geom_object_pt[0] = this->
Wall_pt;
361 el_pt->set_node_update_info(geom_object_pt);
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);
370 MacroElementNodeUpdateMesh::macro_domain_pt() = this->
domain_pt();
435 template<
class ELEMENT>
437 :
public virtual AlgebraicMesh,
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)
457 wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt),
459 wall_pt, xi_lo, fract_mid, xi_hi, nlayer, time_stepper_pt),
463 ELEMENT* el_pt =
new ELEMENT;
464 if (
dynamic_cast<AlgebraicElementBase*
>(el_pt) == 0)
466 std::ostringstream error_message;
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;
474 std::string function_name =
" AlgebraicRefineableQuarterTubeMesh::\n";
475 function_name +=
"AlgebraicRefineableQuarterTubeMesh()";
477 throw OomphLibError(error_message.str(),
478 OOMPH_CURRENT_FUNCTION,
479 OOMPH_EXCEPTION_LOCATION);
485 AlgebraicMesh::add_geom_object_list_pt(
wall_pt);
497 return AlgebraicMesh::self_test();
507 std::ostringstream error_message;
508 error_message <<
"AxialSpacingFctPt has not been implemented "
509 <<
"for the AlgebraicRefineableQuarterTubeMesh\n";
511 std::string function_name =
512 " AlgebraicRefineableQuarterTubeMesh::AxialSpacingFctPt()";
515 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
528 if (update_all_solid_nodes)
530 std::string error_message =
531 "Doesn't make sense to use an AlgebraicMesh with\n";
533 "SolidElements so specifying update_all_solid_nodes=true\n";
534 error_message +=
"doesn't make sense either\n";
536 std::string function_name =
" AlgebraicRefineableQuarterTubeMesh::";
537 function_name +=
"node_update()";
540 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
544 AlgebraicMesh::node_update();
555 unsigned id = node_pt->node_update_fct_id();
579 std::ostringstream error_message;
580 error_message <<
"The node update fct id is " <<
id
584 std::string function_name =
" AlgebraicRefineableQuarterTubeMesh::";
585 function_name +=
"algebraic_node_update()";
587 throw OomphLibError(error_message.str(),
588 OOMPH_CURRENT_FUNCTION,
589 OOMPH_EXCEPTION_LOCATION);
599 node_pt->node_update_fct_id(
id);
602 unsigned n_update =
id.size();
603 for (
unsigned i = 0; i < n_update; i++)
634 AlgebraicNode*& node_pt);
639 AlgebraicNode*& node_pt);
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.
double Centre_box_size
Size of centre box.
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 ®ion_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....
virtual ~MacroElementNodeUpdateRefineableQuarterTubeMesh()
Destructor: empty.
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...
////////////////////////////////////////////////////////////////////// //////////////////////////////...