31 #ifndef OOMPH_CHANNEL_WITH_LEAFLET_MESH_TEMPLATE_CC 32 #define OOMPH_CHANNEL_WITH_LEAFLET_MESH_TEMPLATE_CC 53 template <
class ELEMENT>
58 const double& hleaflet,
60 const unsigned& nleft,
61 const unsigned& nright,
69 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
82 unsigned nmacro = (ny1+ny2)*(nleft+nright);
85 for (
unsigned e=0;
e<nmacro;
e++)
108 for(
unsigned e=0;
e<nleft;
e++)
110 for (
unsigned i=0;
i<nnode_1d;
i++)
114 if(
e!=nleft-1 ||
i!=2)
121 for(
unsigned e=nleft;
e<nleft+nright;
e++)
123 for (
unsigned i=0;
i<nnode_1d;
i++)
134 for (
unsigned k=0;k<ny1;k++)
136 unsigned e = (nleft+nright)*k + nleft-1;
137 for (
unsigned i=0;
i<nnode_1d;
i++)
144 zeta[0]= double(k)*hleaflet/double(ny1)+
145 double(
i)*hleaflet/double(ny1)/double(nnode_1d-1);
163 unsigned e = nleft -1;
171 for (
unsigned i=0;
i<nnode_1d;
i++)
174 construct_boundary_node((
i+1)*nnode_1d-1,time_stepper_pt);
179 zeta[0]=
i*hleaflet/double(ny1)/double(nnode_1d-1);
185 for (
unsigned k=1;k<ny1;k++)
187 e = (nleft+nright)*k + nleft-1;
193 zeta[0]= k*hleaflet/double(ny1);
197 for (
unsigned i=1;
i<nnode_1d;
i++)
200 if( (k==ny1-1)&&(
i==nnode_1d-1) )
209 construct_boundary_node((
i+1)*nnode_1d-1,time_stepper_pt);
216 zeta[0]= double(k)*hleaflet/double(ny1)+
217 double(
i)*hleaflet/double(ny1)/double(nnode_1d-1);
245 template<
class ELEMENT>
256 unsigned nnod=this->
nnode();
257 for (
unsigned j=0;j<nnod;j++)
263 double x=nod_pt->
x(0);
264 double y=nod_pt->
x(1);
272 if( (r[0]!=X_0)||(r[1]!=hleaflet) )
274 std::ostringstream error_stream;
276 <<
"Wall must be in its undeformed position when\n" 277 <<
"algebraic node update information is set up!\n " 278 << r[0] <<
" " << X_0 <<
" " << r[1] <<
" " << hleaflet
282 OOMPH_CURRENT_FUNCTION,
283 OOMPH_EXCEPTION_LOCATION);
291 if( (x<=X_0)&&(y<=hleaflet) )
300 ref_value[3]=zeta[0];
309 geom_object_pt[0]=geom_obj_pt;
317 ref_value[2]=(lleft+x-X_0)/lleft;
329 if((x>=X_0)&&(y<=hleaflet) )
338 ref_value[3]=zeta[0];
347 geom_object_pt[0]=geom_obj_pt;
355 ref_value[2]=(x-X_0)/lright;
366 if((x<=X_0)&&(y>=hleaflet) )
372 ref_value[1]= (y-hleaflet)/(htot-hleaflet);
376 ref_value[2]= (lleft+x-X_0)/lleft;
391 if((x>=X_0)&&(y>=hleaflet) )
397 ref_value[1]= (y-hleaflet)/(htot-hleaflet);
401 ref_value[2]=(x-X_0)/lright;
424 template<
class ELEMENT>
433 node_update_I(t,node_pt);
437 node_update_II(t,node_pt);
441 node_update_III(t,node_pt);
445 node_update_IV(t,node_pt);
449 std::ostringstream error_message;
450 error_message <<
"The node update fct id is " 451 <<
id <<
", but it should only be one of " 457 "AlgebraicChannelWithLeafletMesh::algebraic_node_update()";
460 OOMPH_CURRENT_FUNCTION,
461 OOMPH_EXCEPTION_LOCATION);
470 template<
class ELEMENT>
488 double y0 = ref_value[0];
489 double x0 = -lleft+X_0;
498 leaflet_pt->position(t,s,r_wall);
503 double r = ref_value[2];
507 node_pt->
x(t,0)= x0+ r*(r_wall[0]-x0);
508 node_pt->
x(t,1)= y0+ r*(r_wall[1]-y0);
515 template<
class ELEMENT>
533 double y0 = ref_value[0];
534 double x0 = X_0+lright;
542 leaflet_pt->position(t,s,r_wall);
546 double r = ref_value[2];
549 node_pt->
x(t,0)= r_wall[0]+ r*(x0-r_wall[0]);
550 node_pt->
x(t,1)= r_wall[1]+ r*(y0-r_wall[1]);
557 template<
class ELEMENT>
574 r[0] = r_join[0] + zeta[0]*( X_0-r_join[0]);
575 r[1] = r_join[1] + zeta[0]*( htot-r_join[1]);
581 template<
class ELEMENT>
593 double y0 = ref_value[0];
594 double x0 = -lleft+X_0;
601 slanted_bound_up(t,s,r_line);
605 double r = ref_value[2];
608 node_pt->
x(t,0)= x0+ r*(r_line[0]-x0);
609 node_pt->
x(t,1)= y0+ r*(r_line[1]-y0);
615 template<
class ELEMENT>
627 double y0 = ref_value[0];
628 double x0 = X_0+lright;
636 slanted_bound_up(t,s,r_line);
640 double r = ref_value[2];
643 node_pt->
x(t,0)= r_line[0]+ r*(x0-r_line[0]);
644 node_pt->
x(t,1)= r_line[1]+ r*(y0-r_line[1]);
657 template<
class ELEMENT>
665 if( (
id==1) || (
id==2) )
673 zeta_wall[0]=ref_value[3];
687 geom_object_pt[0]=geom_obj_pt;
virtual void set_coordinates_on_boundary(const unsigned &b, const unsigned &k, const Vector< double > &boundary_zeta)
Set the vector of the k-th generalised boundary coordinates on mesh boundary b. Broken virtual interf...
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement *> &finite_element_pt)
A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this...
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
void node_update_I(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in lower left region (I)
std::vector< bool > Boundary_coordinate_exists
Vector of boolean data that indicates whether the boundary coordinates have been set for the boundary...
void kill_node_update_info(const int &id=0)
Erase algebraic node update information for id-th node update function. Id defaults to 0...
void add_node_update_info(const int &id, AlgebraicMesh *mesh_pt, const Vector< GeomObject *> &geom_object_pt, const Vector< double > &ref_value, const bool &called_from_constructor=false)
Add algebraic update information for node: What's the ID of the mesh update function (typically used ...
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
ChannelWithLeafletDomain * domain_pt()
Access function to domain.
A general Finite Element class.
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
GeomObject * Leaflet_pt
Pointer to GeomObject that represents the leaflet.
int node_update_fct_id()
Default (usually first if there are multiple ones) node update fct id.
void node_update_IV(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in upper right region (IV)
void slanted_bound_up(const unsigned &t, const Vector< double > &zeta, Vector< double > &r)
Helper function.
Vector< double > & vector_ref_value()
Return vector of reference values involved in default (usually first) update function.
void add_node_pt(Node *const &node_pt)
Add a (pointer to a) node to the mesh.
virtual void set_macro_elem_pt(MacroElement *macro_elem_pt)
Set pointer to macro element – can be overloaded in derived elements to perform additional tasks...
void update_node_update(AlgebraicNode *&node_pt)
Update the node update data for specified node following any mesh adapation.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
void node_update_III(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in upper left region (III)
void setup_boundary_element_info()
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
ChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
unsigned long nnode() const
Return number of nodes in the mesh.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
ChannelWithLeafletDomain * Domain_pt
Pointer to domain.
double htot()
Total height of domain (width of channel)
virtual void node_update(const bool &update_all_solid_nodes=false)
Update nodal positions in response to changes in the domain shape. Uses the FiniteElement::get_x(...) function for FiniteElements and doesn't do anything for other element types. If a MacroElement pointer has been set for a FiniteElement, the MacroElement representation is used to update the nodal positions; if not get_x(...) uses the FE interpolation and thus leaves the nodal positions unchanged. Virtual, so it can be overloaded by specific meshes, such as AlgebraicMeshes or SpineMeshes. Generally, this function updates the position of all nodes in response to changes in the boundary position. However, we ignore all SolidNodes since their position is computed as part of the solution – unless the bool flag is set to true. Such calls are typically made when the initial mesh is created and/or after a mesh has been refined repeatedly before the start of the computation.
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overloa...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
void node_update_II(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in lower right region (II)
void setup_algebraic_node_update()
Function to setup the algebraic node update.
virtual void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
A geometric object may be composed of may sub-objects (e.g. a finite-element representation of a boun...
double lright()
Length of domain to the right of leaflet.
double lleft()
Length of domain to the left of leaflet.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Vector< GeomObject * > & vector_geom_object_pt(const int &id)
Return vector of geometric objects involved in id-th update function.
double hleaflet()
Height of leaflet.
void remove_boundary_nodes()
Clear all pointers to boundary nodes.