30 #ifndef OOMPH_QUARTER_TUBE_MESH_HEADER 31 #define OOMPH_QUARTER_TUBE_MESH_HEADER 34 #include "../generic/refineable_brick_mesh.h" 35 #include "../generic/macro_element.h" 36 #include "../generic/domain.h" 37 #include "../generic/algebraic_elements.h" 38 #include "../generic/brick_mesh.h" 39 #include "../generic/macro_element_node_update_element.h" 69 template <
class ELEMENT>
81 const Vector<double>& xi_lo,
82 const double& fract_mid,
83 const Vector<double>& xi_hi,
84 const unsigned& nlayer,
85 TimeStepper* time_stepper_pt=
86 &Mesh::Default_TimeStepper);
165 template<
class ELEMENT>
167 public RefineableBrickMesh<ELEMENT>
181 const Vector<double>& xi_lo,
182 const double& fract_mid,
183 const Vector<double>& xi_hi,
184 const unsigned& nlayer,
185 TimeStepper* time_stepper_pt=
186 &Mesh::Default_TimeStepper):
188 nlayer,time_stepper_pt)
191 for (
unsigned ielem=0;ielem<QuarterTubeMesh<ELEMENT>::nelement();ielem++)
193 dynamic_cast<RefineableQElement<3>*
>(
195 set_macro_elem_pt(this->
Domain_pt->macro_element_pt(ielem));
201 Vector<TreeRoot*> trees_pt;
202 for (
unsigned iel=0;iel<QuarterTubeMesh<ELEMENT>::nelement();iel++)
205 ELEMENT* ref_el_pt=
dynamic_cast<ELEMENT*
>(el_pt);
206 OcTreeRoot* octree_root_pt=
new OcTreeRoot(ref_el_pt);
207 trees_pt.push_back(octree_root_pt);
209 this->Forest_pt =
new OcTreeForest(trees_pt);
213 unsigned success_flag=
214 dynamic_cast<OcTreeForest*
>(this->Forest_pt)->self_test();
217 oomph_info <<
"Successfully built octree forest " << std::endl;
222 "Trouble in building octree forest ",
223 OOMPH_CURRENT_FUNCTION,
224 OOMPH_EXCEPTION_LOCATION);
245 class MacroElementNodeUpdateNode;
250 template<
class ELEMENT>
252 public virtual MacroElementNodeUpdateMesh,
268 const Vector<double>& xi_lo,
269 const double& fract_mid,
270 const Vector<double>& xi_hi,
271 const unsigned& nlayer,
272 TimeStepper* time_stepper_pt=
273 &Mesh::Default_TimeStepper) :
274 MacroElementNodeUpdateMesh(),
276 nlayer,time_stepper_pt),
278 nlayer,time_stepper_pt)
282 ELEMENT* el_pt=
new ELEMENT;
283 if (dynamic_cast<MacroElementNodeUpdateElementBase*>(el_pt)==0)
285 std::ostringstream error_message;
287 <<
"Base class for ELEMENT in " 288 <<
"MacroElementNodeUpdateRefineableQuarterTubeMesh needs" 289 <<
"to be of type MacroElementNodeUpdateElement!\n";
290 error_message <<
"Whereas it is: typeid(el_pt).name()" 291 <<
typeid(el_pt).name()
294 std::string function_name =
295 "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
297 "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh()";
299 throw OomphLibError(error_message.str(),
300 OOMPH_CURRENT_FUNCTION,
301 OOMPH_EXCEPTION_LOCATION);
309 this->setup_macro_element_node_update();
323 if (update_all_solid_nodes)
325 std::string error_message =
326 "Doesn't make sense to use an MacroElementNodeUpdateMesh with\n";
328 "SolidElements so specifying update_all_solid_nodes=true\n";
329 error_message +=
"doesn't make sense either\n";
331 std::string function_name =
332 "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
333 function_name +=
"node_update()";
335 throw OomphLibError(error_message,
336 OOMPH_CURRENT_FUNCTION,
337 OOMPH_EXCEPTION_LOCATION);
340 MacroElementNodeUpdateMesh::node_update();
350 unsigned n_element = this->nelement();
351 for(
unsigned i=0;i<n_element;i++)
354 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(this->element_pt(i));
358 MacroElementNodeUpdateElementBase* m_el_pt=
dynamic_cast< 359 MacroElementNodeUpdateElementBase*
>(el_pt);
362 std::ostringstream error_message;
364 <<
"Failed to upcast to MacroElementNodeUpdateElementBase\n";
366 <<
"Element must be derived from MacroElementNodeUpdateElementBase\n";
367 error_message <<
"but it is of type " <<
typeid(el_pt).name();
369 std::string function_name =
370 "MacroElementNodeUpdateRefineableQuaterCircleSectorMesh::\n";
371 function_name +=
"setup_macro_element_node_update()";
373 throw OomphLibError(error_message.str(),
374 OOMPH_CURRENT_FUNCTION,
375 OOMPH_EXCEPTION_LOCATION);
379 Vector<GeomObject*> geom_object_pt(1);
380 geom_object_pt[0] = this->
Wall_pt;
384 el_pt->set_node_update_info(geom_object_pt);
388 Vector<GeomObject*> geom_object_pt(1);
389 geom_object_pt[0] = this->
Wall_pt;
390 MacroElementNodeUpdateMesh::set_geom_object_vector_pt(geom_object_pt);
393 MacroElementNodeUpdateMesh::macro_domain_pt()=this->
domain_pt();
461 template<
class ELEMENT>
463 public virtual AlgebraicMesh,
477 const Vector<double>& xi_lo,
478 const double& fract_mid,
479 const Vector<double>& xi_hi,
480 const unsigned& nlayer,
481 const double centre_box_size=1.0,
482 TimeStepper* time_stepper_pt=
483 &Mesh::Default_TimeStepper) :
485 nlayer, time_stepper_pt),
487 nlayer, time_stepper_pt),
488 Centre_box_size(centre_box_size)
492 ELEMENT* el_pt=
new ELEMENT;
493 if (dynamic_cast<AlgebraicElementBase*>(el_pt)==0)
495 std::ostringstream error_message;
497 error_message <<
"Base class for ELEMENT in " 498 <<
"AlgebraicRefineableQuarterTubeMesh needs" 499 <<
"to be of type AlgebraicElement!\n";
500 error_message <<
"Whereas it is: typeid(el_pt).name()" 501 <<
typeid(el_pt).name()
504 std::string function_name =
505 " AlgebraicRefineableQuarterTubeMesh::\n";
506 function_name +=
"AlgebraicRefineableQuarterTubeMesh()";
508 throw OomphLibError(error_message.str(),
509 OOMPH_CURRENT_FUNCTION,
510 OOMPH_EXCEPTION_LOCATION);
516 AlgebraicMesh::add_geom_object_list_pt(wall_pt);
519 setup_algebraic_node_update();
528 return AlgebraicMesh::self_test();
538 std::ostringstream error_message;
539 error_message <<
"AxialSpacingFctPt has not been implemented " 540 <<
"for the AlgebraicRefineableQuarterTubeMesh\n";
542 std::string function_name =
543 " AlgebraicRefineableQuarterTubeMesh::AxialSpacingFctPt()";
545 throw OomphLibError(error_message.str(),
546 OOMPH_CURRENT_FUNCTION,
547 OOMPH_EXCEPTION_LOCATION);
560 if (update_all_solid_nodes)
562 std::string error_message =
563 "Doesn't make sense to use an AlgebraicMesh with\n";
565 "SolidElements so specifying update_all_solid_nodes=true\n";
566 error_message +=
"doesn't make sense either\n";
568 std::string function_name =
569 " AlgebraicRefineableQuarterTubeMesh::";
570 function_name +=
"node_update()";
572 throw OomphLibError(error_message,
573 OOMPH_CURRENT_FUNCTION,
574 OOMPH_EXCEPTION_LOCATION);
578 AlgebraicMesh::node_update();
589 unsigned id=node_pt->node_update_fct_id();
597 node_update_central_region(t,node_pt);
600 case Lower_right_region:
603 node_update_lower_right_region(t,node_pt);
606 case Upper_left_region:
609 node_update_upper_left_region(t,node_pt);
614 std::ostringstream error_message;
615 error_message <<
"The node update fct id is " 616 <<
id <<
", but it should only be one of " 617 << Central_region <<
", " 618 << Lower_right_region <<
" or " 619 << Upper_left_region << std::endl;
620 std::string function_name =
621 " AlgebraicRefineableQuarterTubeMesh::";
622 function_name +=
"algebraic_node_update()";
624 throw OomphLibError(error_message.str(),
625 OOMPH_CURRENT_FUNCTION,
626 OOMPH_EXCEPTION_LOCATION);
636 node_pt->node_update_fct_id(
id);
639 unsigned n_update=
id.size();
640 for (
unsigned i=0;i<n_update;i++)
642 update_node_update_in_region(node_pt,
id[i]);
653 enum{Central_region, Lower_right_region, Upper_left_region};
663 void node_update_central_region(
const unsigned& t,
664 AlgebraicNode*& node_pt);
668 void node_update_lower_right_region(
const unsigned& t,
669 AlgebraicNode*& node_pt);
673 void node_update_upper_left_region(
const unsigned& t,
674 AlgebraicNode*& node_pt);
677 void setup_algebraic_node_update();
681 void update_node_update_in_region(AlgebraicNode*& node_pt,
AxialSpacingFctPt & axial_spacing_fct_pt()
Function pointer for function that implements axial spacing of macro elements.
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 ...
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...
void update_node_update(AlgebraicNode *&node_pt)
Update the node update info for specified algebraic node following any spatial mesh adaptation...
virtual ~RefineableQuarterTubeMesh()
Destructor: empty.
unsigned self_test()
Run self-test for algebraic mesh – return 0/1 for OK/failure.
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 ...
virtual QuarterTubeDomain::AxialSpacingFctPt & axial_spacing_fct_pt()
Function pointer for function for axial spacing.
QuarterTubeDomain::BLSquashFctPt & bl_squash_fct_pt()
Function pointer for function that squashes the outer macro elements towards the wall by mapping the ...
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...
double(* AxialSpacingFctPt)(const double &xi)
Typedef for function pointer for function that implements axial spacing of macro elements.
Vector< double > Xi_hi
Upper limits for the coordinates along the wall.
Vector< double > Xi_lo
Lower limits for the coordinates along the wall.
BLSquashFctPt & bl_squash_fct_pt()
Function pointer for function that squashes the outer two macro elements towards the wall by mapping ...
void node_update(const bool &update_all_solid_nodes=false)
Resolve mesh update: Update current nodal positions via sparse MacroElement-based update...
QuarterTubeDomain::AxialSpacingFctPt & axial_spacing_fct_pt()
Broken version of the QuarterTubeDomain function Function is broken because axial spacing isn't imple...
double Fract_mid
Fraction along wall where outer ring is to be divided.
void setup_macro_element_node_update()
Setup all the information that's required for MacroElement-based node update: Tell the elements that ...
3D quarter tube mesh class. The domain is specified by the GeomObject that identifies boundary 3...
virtual ~QuarterTubeMesh()
Destructor: empty.
double(* BLSquashFctPt)(const double &s)
Typedef for function pointer for function that squashes the outer two macro elements towards the wall...
GeomObject * Wall_pt
Pointer to the geometric object that represents the curved wall.
Quarter tube as domain. Domain is bounded by curved boundary which is represented by a GeomObject...
GeomObject *& wall_pt()
Access function to GeomObject representing wall.
AlgebraicMesh version of RefineableQuarterTubeMesh.
MacroElementNodeUpdate version of RefineableQuarterTubeMesh.
double Lambda_x
Fractional width of central region.
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)...
QuarterTubeDomain * Domain_pt
Pointer to domain.
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...
QuarterTubeDomain * domain_pt()
Access function to domain.
double Lambda_y
Fractional height of central region.
virtual ~MacroElementNodeUpdateRefineableQuarterTubeMesh()
Destructor: empty.
double Centre_box_size
Size of centre box.
QuarterTubeDomain * domain_pt() const
Access function to underlying domain.