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)