31 #ifndef OOMPH_CHANNEL_WITH_LEAFLET_MESH_TEMPLATE_CC 32 #define OOMPH_CHANNEL_WITH_LEAFLET_MESH_TEMPLATE_CC 53 template <
class ELEMENT>
55 GeomObject* leaflet_pt,
58 const double& hleaflet,
60 const unsigned& nleft,
61 const unsigned& nright,
64 TimeStepper* time_stepper_pt)
69 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
82 unsigned nmacro = (ny1+ny2)*(nleft+nright);
85 for (
unsigned e=0;e<nmacro;e++)
88 FiniteElement* el_pt=this->finite_element_pt(e);
91 el_pt->set_macro_elem_pt(this->
Domain_pt->macro_element_pt(e));
99 this->set_nboundary(7);
102 this->remove_boundary_nodes(0);
105 unsigned nnode_1d=this->finite_element_pt(0)->nnode_1d();
108 for(
unsigned e=0;e<nleft;e++)
110 for (
unsigned i=0;i<nnode_1d;i++)
112 Node* nod_pt=this->finite_element_pt(e)->node_pt(i);
114 if( e!=nleft-1 || i!=2)
116 this->add_boundary_node(0, nod_pt);
121 for(
unsigned e=nleft;e<nleft+nright;e++)
123 for (
unsigned i=0;i<nnode_1d;i++)
125 Node* nod_pt=this->finite_element_pt(e)->node_pt(i);
126 this->add_boundary_node(6, nod_pt);
131 Vector<double> zeta(1);
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++)
139 Node* nod_pt=this->finite_element_pt(e)->node_pt((i+1)*nnode_1d-1);
140 this->convert_to_boundary_node(nod_pt);
141 this->add_boundary_node(4, nod_pt);
144 zeta[0]= double(k)*hleaflet/double(ny1)+
145 double(i)*hleaflet/double(ny1)/double(nnode_1d-1);
146 nod_pt->set_coordinates_on_boundary(4,zeta);
163 unsigned e = nleft -1;
171 for (
unsigned i=0;i<nnode_1d;i++)
173 nod_pt=this->finite_element_pt(e)->
174 construct_boundary_node((i+1)*nnode_1d-1,time_stepper_pt);
175 this->add_boundary_node(5, nod_pt);
176 if(i==0){this->add_boundary_node(0, nod_pt);}
177 this->add_node_pt(nod_pt);
179 zeta[0]= i*hleaflet/double(ny1)/double(nnode_1d-1);
180 nod_pt->set_coordinates_on_boundary(5,zeta);
185 for (
unsigned k=1;k<ny1;k++)
187 e = (nleft+nright)*k + nleft-1;
190 this->finite_element_pt(e)->node_pt(nnode_1d-1)=nod_pt;
191 this->add_boundary_node(5,nod_pt);
193 zeta[0]= k*hleaflet/double(ny1);
194 nod_pt->set_coordinates_on_boundary(5,zeta);
197 for (
unsigned i=1;i<nnode_1d;i++)
200 if( (k==ny1-1)&&(i==nnode_1d-1) )
203 nod_pt=this->finite_element_pt(e)->node_pt(nnode_1d*nnode_1d-1);
208 nod_pt=this->finite_element_pt(e)->
209 construct_boundary_node((i+1)*nnode_1d-1,time_stepper_pt);
210 this->add_node_pt(nod_pt);
214 this->add_boundary_node(5, nod_pt);
216 zeta[0]= double(k)*hleaflet/double(ny1)+
217 double(i)*hleaflet/double(ny1)/double(nnode_1d-1);
218 nod_pt->set_coordinates_on_boundary(5,zeta);
227 this->setup_boundary_element_info();
230 this->Boundary_coordinate_exists[4] =
true;
231 this->Boundary_coordinate_exists[5] =
true;
245 template<
class ELEMENT>
256 unsigned nnod=this->nnode();
257 for (
unsigned j=0;j<nnod;j++)
260 AlgebraicNode* nod_pt=node_pt(j);
263 double x=nod_pt->x(0);
264 double y=nod_pt->x(1);
268 Vector<double> zeta(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);
288 Vector<double> ref_value(4);
291 if( (x<=
X_0)&&(y<=hleaflet) )
298 Vector<double> zeta(1);
300 ref_value[3]=zeta[0];
303 GeomObject* geom_obj_pt;
305 this->
Leaflet_pt->locate_zeta(zeta,geom_obj_pt,s);
308 Vector<GeomObject*> geom_object_pt(1);
309 geom_object_pt[0]=geom_obj_pt;
317 ref_value[2]=(lleft+x-
X_0)/lleft;
322 nod_pt->add_node_update_info(
329 if((x>=
X_0)&&(y<=hleaflet) )
336 Vector<double> zeta(1);
338 ref_value[3]=zeta[0];
341 GeomObject* geom_obj_pt;
343 this->
Leaflet_pt->locate_zeta(zeta,geom_obj_pt,s);
346 Vector<GeomObject*> geom_object_pt(1);
347 geom_object_pt[0]=geom_obj_pt;
355 ref_value[2]=(x-
X_0)/lright;
359 nod_pt->add_node_update_info(
366 if((x<=
X_0)&&(y>=hleaflet) )
372 ref_value[1]= (y-hleaflet)/(htot-hleaflet);
376 ref_value[2]= (lleft+x-
X_0)/lleft;
379 Vector<GeomObject*> geom_object_pt(1);
384 nod_pt->add_node_update_info(
391 if((x>=
X_0)&&(y>=hleaflet) )
397 ref_value[1]= (y-hleaflet)/(htot-hleaflet);
401 ref_value[2]=(x-
X_0)/lright;
404 Vector<GeomObject*> geom_object_pt(1);
409 nod_pt->add_node_update_info(
424 template<
class ELEMENT>
426 const unsigned& t, AlgebraicNode*& node_pt)
428 unsigned id=node_pt->node_update_fct_id();
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 " 456 std::string function_name =
457 "AlgebraicChannelWithLeafletMesh::algebraic_node_update()";
459 throw OomphLibError(error_message.str(),
460 OOMPH_CURRENT_FUNCTION,
461 OOMPH_EXCEPTION_LOCATION);
470 template<
class ELEMENT>
472 const unsigned&t, AlgebraicNode*& node_pt)
478 Vector<double> ref_value(node_pt->vector_ref_value());
481 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
484 GeomObject* leaflet_pt=geom_object_pt[0];
488 double y0 = ref_value[0];
489 double x0 = -lleft+
X_0;
497 Vector<double> r_wall(2);
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>
517 const unsigned&t, AlgebraicNode*& node_pt)
523 Vector<double> ref_value(node_pt->vector_ref_value());
526 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
529 GeomObject* leaflet_pt=geom_object_pt[0];
533 double y0 = ref_value[0];
534 double x0 =
X_0+lright;
541 Vector<double> r_wall(2);
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>
560 const Vector<double>& zeta,
567 Vector<double> xi(1);
570 Vector<double> r_join(2);
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>
583 const unsigned&t, AlgebraicNode*& node_pt)
589 Vector<double> ref_value(node_pt->vector_ref_value());
593 double y0 = ref_value[0];
594 double x0 = -lleft+
X_0;
600 Vector<double> r_line(2);
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>
617 const unsigned&t, AlgebraicNode*& node_pt)
623 Vector<double> ref_value(node_pt->vector_ref_value());
627 double y0 = ref_value[0];
628 double x0 =
X_0+lright;
635 Vector<double> r_line(2);
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>
659 AlgebraicNode*& node_pt)
663 unsigned id=node_pt->node_update_fct_id();
665 if( (
id==1) || (
id==2) )
669 Vector<double> ref_value(node_pt->vector_ref_value());
672 Vector<double> zeta_wall(1);
673 zeta_wall[0]=ref_value[3];
677 GeomObject* geom_obj_pt;
678 this->
Leaflet_pt->locate_zeta(zeta_wall,geom_obj_pt,s);
681 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
687 geom_object_pt[0]=geom_obj_pt;
697 node_pt->kill_node_update_info(1);
700 node_pt->add_node_update_info(
709 node_pt->kill_node_update_info(2);
712 node_pt->add_node_update_info(
double X_0
Orientation (x-coordinate of step plane)
void node_update_I(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in lower left region (I)
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.
GeomObject * Leaflet_pt
Pointer to GeomObject that represents the leaflet.
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.
void update_node_update(AlgebraicNode *&node_pt)
Update the node update data for specified node following any mesh adapation.
void node_update_III(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in upper left region (III)
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...
ChannelWithLeafletDomain * Domain_pt
Pointer to domain.
double htot()
Total height of domain (width of channel)
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.
double lright()
Length of domain to the right of leaflet.
double lleft()
Length of domain to the left of leaflet.
double hleaflet()
Height of leaflet.