30 #ifndef OOMPH_FISH_MESH_HEADER 31 #define OOMPH_FISH_MESH_HEADER 34 #include "../generic/refineable_quad_mesh.h" 35 #include "../generic/macro_element.h" 36 #include "../generic/domain.h" 37 #include "../generic/algebraic_elements.h" 38 #include "../generic/quad_mesh.h" 39 #include "../generic/macro_element_node_update_element.h" 42 #include "../generic/algebraic_elements.h" 45 #include "../generic/macro_element_node_update_element.h" 58 template<
class ELEMENT>
67 FishMesh(TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper);
73 TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper);
105 void build_mesh(TimeStepper* time_stepper_pt);
133 template<
class ELEMENT>
135 public RefineableQuadMesh<ELEMENT>
160 TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper)
161 :
FishMesh<ELEMENT>(back_pt,time_stepper_pt)
181 void setup_adaptivity();
194 class MacroElementNodeUpdateNode;
207 template<
class ELEMENT>
209 public virtual MacroElementNodeUpdateMesh,
219 TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper) :
220 FishMesh<ELEMENT>(back_pt,time_stepper_pt),
224 ELEMENT* el_pt=
new ELEMENT;
225 if (dynamic_cast<MacroElementNodeUpdateElementBase*>(el_pt)==0)
227 std::ostringstream error_message;
229 <<
"Base class for ELEMENT in " 230 <<
"MacroElementNodeUpdateRefineableFishMesh needs" 231 <<
"to be of type MacroElementNodeUpdateElement!\n";
232 error_message <<
"Whereas it is: typeid(el_pt).name()" 233 <<
typeid(el_pt).name()
236 std::string function_name =
237 "MacroElementNodeUpdateRefineableFishMesh::\n";
239 "MacroElementNodeUpdateRefineableFishMesh()";
241 throw OomphLibError(error_message.str(),
242 OOMPH_CURRENT_FUNCTION,
243 OOMPH_EXCEPTION_LOCATION);
252 unsigned n_element = this->nelement();
253 for(
unsigned i=0;i<n_element;i++)
256 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(this->element_pt(i));
260 MacroElementNodeUpdateElementBase* m_el_pt=
dynamic_cast< 261 MacroElementNodeUpdateElementBase*
>(el_pt);
264 std::ostringstream error_message;
266 <<
"Failed to upcast to MacroElementNodeUpdateElementBase\n";
268 <<
"Element must be derived from MacroElementNodeUpdateElementBase\n";
269 error_message <<
"but it is of type " <<
typeid(el_pt).name();
271 std::string function_name =
272 "MacroElementNodeUpdateRefineableFishMesh::\n";
273 function_name +=
"MacroElementNodeUpdateRefinableFishMesh()";
275 throw OomphLibError(error_message.str(),
276 OOMPH_CURRENT_FUNCTION,
277 OOMPH_EXCEPTION_LOCATION);
281 Vector<GeomObject*> geom_object_pt(1);
282 geom_object_pt[0] = this->
Back_pt;
286 el_pt->set_node_update_info(geom_object_pt);
290 Vector<GeomObject*> geom_object_pt(1);
291 geom_object_pt[0] = this->
Back_pt;
292 MacroElementNodeUpdateMesh::set_geom_object_vector_pt(geom_object_pt);
295 MacroElementNodeUpdateMesh::macro_domain_pt()=this->
domain_pt();
310 if (update_all_solid_nodes)
312 std::string error_message =
313 "Doesn't make sense to use an MacroElementNodeUpdateMesh with\n";
315 "SolidElements so specifying update_all_solid_nodes=true\n";
316 error_message +=
"doesn't make sense either\n";
318 std::string function_name =
319 "MacroElementNodeUpdateRefineableFishMesh::";
320 function_name +=
"node_update()";
322 throw OomphLibError(error_message,
323 OOMPH_CURRENT_FUNCTION,
324 OOMPH_EXCEPTION_LOCATION);
327 MacroElementNodeUpdateMesh::node_update();
348 template<
class ELEMENT>
361 setup_algebraic_node_update();
368 TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper) :
369 FishMesh<ELEMENT>(back_pt,time_stepper_pt)
372 AlgebraicMesh::add_geom_object_list_pt(back_pt);
375 setup_algebraic_node_update();
387 unsigned id=node_pt->node_update_fct_id();
392 node_update_in_body(t,node_pt);
397 node_update_in_fin(t,node_pt);
401 std::ostringstream error_message;
402 error_message <<
"The node update fct id is " 403 <<
id <<
", but it should only be one of " 408 std::string function_name =
"AlgebraicFishMesh::algebraic_node_update()";
410 throw OomphLibError(error_message.str(),
411 OOMPH_CURRENT_FUNCTION,
412 OOMPH_EXCEPTION_LOCATION);
422 virtual void node_update(
const bool& update_all_solid_nodes=
false)
425 if (update_all_solid_nodes)
427 std::string error_message =
428 "Doesn't make sense to use an AlgebraicMesh with\n";
430 "SolidElements so specifying update_all_solid_nodes=true\n";
431 error_message +=
"doesn't make sense either\n";
433 std::string function_name =
434 "AlgebraicFishMesh::node_update()";
436 throw OomphLibError(error_message,
437 OOMPH_CURRENT_FUNCTION,
438 OOMPH_EXCEPTION_LOCATION);
441 AlgebraicMesh::node_update();
467 Vector<double> zeta(1);
468 zeta[0]=0.5*(xi_nose+xi_tail);
471 GeomObject* geom_obj_pt=0;
472 this->
Back_pt->locate_zeta(zeta,geom_obj_pt,s);
474 if ((geom_obj_pt!=this->
Back_pt)||(s[0]!=zeta[0]))
476 std::ostringstream error_message;
478 <<
"AlgebraicFishMesh only works with GeomObjects\n" 479 <<
"that do not contain sub-elements (e.g. GeomObjects\n" 480 <<
"that represent a wall finite element mesh!\n" 481 <<
"Back_pt : " << this->
Back_pt << std::endl
482 <<
"geom_obj_pt: " << geom_obj_pt << std::endl
483 <<
"s[0] : " << s[0] << std::endl
484 <<
"zeta[0] : " << zeta[0] << std::endl;
486 throw OomphLibError(error_message.str(),
487 OOMPH_CURRENT_FUNCTION,
488 OOMPH_EXCEPTION_LOCATION);
497 void node_update_in_body(
const unsigned& t, AlgebraicNode*& node_pt);
500 void node_update_in_fin(
const unsigned& t, AlgebraicNode*& node_pt);
505 void setup_algebraic_node_update();
522 template<
class ELEMENT>
538 &Mesh::Default_TimeStepper) :
554 TimeStepper* time_stepper_pt=
555 &Mesh::Default_TimeStepper) :
556 FishMesh<ELEMENT>(back_pt,time_stepper_pt),
GeomObject * Back_pt
Pointer to fish back.
RefineableFishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to timestepper – defaults to (Steady) default timestepper defined in the M...
Fish shaped mesh with algebraic node update function for nodes.
AlgebraicFishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to timestepper. (defaults to (Steady) default timestepper defined in Mesh) ...
Fish shaped mesh. The geometry is defined by the Domain object FishDomain.
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...
virtual ~AlgebraicRefineableFishMesh()
Destructor: empty.
void build_mesh(TimeStepper *time_stepper_pt)
Build the mesh, using the geometric object identified by Back_pt.
virtual ~MacroElementNodeUpdateRefineableFishMesh()
Destructor: empty.
bool Must_kill_fish_back
Do I need to kill the fish back geom object?
double & xi_tail()
End coordinate on wall (near tail)
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...
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...
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. (defaults to (Steady) default timestepper defined in Mesh)
void node_update(const bool &update_all_solid_nodes=false)
Resolve mesh update: NodeUpdate current nodal positions via sparse MacroElement-based update...
void update_node_update(AlgebraicNode *&node_pt)
Update the geometric references that are used to update node after mesh adaptation. We're assuming that the GeomObject that specifies the fish back does not have sub-objects, therefore no update is required – all reference values can simply be scaled. We simply paranoid-check that this is actually the case, by checking if locate_zeta() returns the original data.
virtual ~FishMesh()
Destructor: Kill the geom object that represents the fish's back (if necessary)
virtual ~RefineableFishMesh()
Destructor: Empty – all cleanup gets handled in the base classes.
FishDomain * Domain_pt
Pointer to domain.
GeomObject *& fish_back_pt()
Access function to geom object that represents the fish's back.
Fish shaped domain, represented by four MacroElements. Shape is parametrised by GeomObject that repre...
AlgebraicRefineableFishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
virtual ~AlgebraicFishMesh()
Destructor: empty.
FishDomain *& domain_pt()
Access function to FishDomain.
Refineable fish shaped mesh with algebraic node update function.
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...
FishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to timestepper (defaults to the (Steady) default timestepper defined in Mes...
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...
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
double & xi_nose()
Start coordinate on wall (near nose)