30 #ifndef OOMPH_COLLAPSIBLE_CHANNEL_MESH_TEMPLATE_CC 31 #define OOMPH_COLLAPSIBLE_CHANNEL_MESH_TEMPLATE_CC 47 template <
class ELEMENT>
50 const unsigned& ncollapsible,
51 const unsigned& ndown,
54 const double& lcollapsible,
58 TimeStepper* time_stepper_pt)
60 lup+lcollapsible+ldown, ly,
62 Nup(nup), Ncollapsible(ncollapsible), Ndown(ndown), Ny(ny),
66 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
71 lup,lcollapsible, ldown, ly,
75 unsigned nmacro=(nup+ncollapsible+ndown)*ny;
78 for (
unsigned e=0;e<nmacro;e++)
81 FiniteElement* el_pt=this->finite_element_pt(e);
86 el_pt->set_macro_elem_pt(this->Domain_pt->macro_element_pt(e));
104 unsigned nbound=this->nboundary();
105 for (
unsigned b=0;b<nbound;b++)
109 this->remove_boundary_nodes(b);
114 unsigned nnod=this->nnode();
115 for (
unsigned j=0;j<nnod;j++)
117 if (this->node_pt(j)->is_on_boundary())
119 std::ostringstream error_message;
120 error_message <<
"Node " << j <<
"is still on boundary " << std::endl;
122 throw OomphLibError(error_message.str(),
123 OOMPH_CURRENT_FUNCTION,
124 OOMPH_EXCEPTION_LOCATION);
130 this->set_nboundary(6);
133 unsigned nnode_1d=this->finite_element_pt(0)->nnode_1d();
136 Vector<double> zeta(1);
139 unsigned first_collapsible=(ny-1)*(nup+ncollapsible+ndown)+nup;
143 double dzeta= lcollapsible/double(ncollapsible);
147 unsigned nelem=this->nelement();
148 for (
unsigned e=0;e<nelem;e++)
151 if (e<nup+ncollapsible+ndown)
153 for (
unsigned i=0;i<nnode_1d;i++)
155 this->add_boundary_node(0, this->finite_element_pt(e)->node_pt(i));
159 if ((e>(ny-1)*(nup+ncollapsible+ndown)-1)&&
160 (e<(ny-1)*(nup+ncollapsible+ndown)+nup))
162 for (
unsigned i=0;i<nnode_1d;i++)
164 this->add_boundary_node(4,
165 this->finite_element_pt(e)->node_pt((nnode_1d-1)*nnode_1d+i));
169 if ((e>(ny-1)*(nup+ncollapsible+ndown)+nup-1)&&
170 (e<(ny-1)*(nup+ncollapsible+ndown)+nup+ncollapsible))
172 for (
unsigned i=0;i<nnode_1d;i++)
174 this->add_boundary_node(3,
175 this->finite_element_pt(e)->node_pt((nnode_1d-1)*nnode_1d+i));
178 unsigned ix=e-first_collapsible;
181 zeta[0]=double(ix)*dzeta+double(i)*dzeta/double(nnode_1d-1);
184 this->finite_element_pt(e)->node_pt((nnode_1d-1)*nnode_1d+i)->
185 set_coordinates_on_boundary(3,zeta);
189 if ((e>(ny-1)*(nup+ncollapsible+ndown)+nup+ncollapsible-1)&&
190 (e<ny*(nup+ncollapsible+ndown)))
192 for (
unsigned i=0;i<nnode_1d;i++)
194 this->add_boundary_node(2,
195 this->finite_element_pt(e)->node_pt((nnode_1d-1)*nnode_1d+i));
199 if (e%(nup+ncollapsible+ndown)==0)
201 for (
unsigned i=0;i<nnode_1d;i++)
203 this->add_boundary_node(5,
204 this->finite_element_pt(e)->node_pt(i*nnode_1d));
208 if (e%(nup+ncollapsible+ndown)==(nup+ncollapsible+ndown)-1)
210 for (
unsigned i=0;i<nnode_1d;i++)
212 this->add_boundary_node(1,
213 this->finite_element_pt(e)->node_pt((i+1)*nnode_1d-1));
220 this->setup_boundary_element_info();
223 this->Boundary_coordinate_exists[3] =
true;
239 template<
class ELEMENT>
241 const unsigned& t, AlgebraicNode*& node_pt)
259 if (t>node_pt->position_time_stepper_pt()->nprev_values())
261 std::string error_message =
262 "Trying to update the nodal position at a time level";
263 error_message +=
"beyond the number of previous values in the nodes'";
264 error_message +=
"position timestepper. This seems highly suspect!";
265 error_message +=
"If you're sure the code behaves correctly";
266 error_message +=
"in your application, remove this warning ";
267 error_message +=
"or recompile with PARNOID switched off.";
269 std::string function_name =
270 "AlgebraicCollapsibleChannelMesh::";
271 function_name +=
"algebraic_node_update()";
273 throw OomphLibError(error_message,
274 OOMPH_CURRENT_FUNCTION,
275 OOMPH_EXCEPTION_LOCATION);
280 Vector<double> ref_value(node_pt->vector_ref_value());
284 double x_bottom=ref_value[0];
289 double fract=ref_value[1];
305 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
309 GeomObject* geom_obj_pt=geom_object_pt[0];
312 Vector<double> r_wall(2);
313 geom_obj_pt->position(t,s,r_wall);
316 node_pt->x(t,0)=x_bottom+fract*(r_wall[0]-x_bottom);
317 node_pt->x(t,1)=fract*r_wall[1];
329 template<
class ELEMENT>
337 unsigned nnod=this->nnode();
338 for (
unsigned j=0;j<nnod;j++)
343 AlgebraicNode* nod_pt=node_pt(j);
346 double x=nod_pt->x(0);
347 double y=nod_pt->x(1);
350 if ( (x>=l_up) && (x<=(l_up+l_collapsible)) )
354 Vector<double> zeta(1);
365 GeomObject* geom_obj_pt;
367 this->
Wall_pt->locate_zeta(zeta,geom_obj_pt,s);
370 Vector<double> r_wall(2);
371 geom_obj_pt->position(s,r_wall);
375 if ((std::fabs(r_wall[0]-x)>1.0e-15)&&(std::fabs(r_wall[1]-y)>1.0e-15))
377 std::ostringstream error_stream;
379 <<
"Wall must be in its undeformed position when\n" 380 <<
"algebraic node update information is set up!\n " 381 <<
"x-discrepancy: " << std::fabs(r_wall[0]-x) << std::endl
382 <<
"y-discrepancy: " << std::fabs(r_wall[1]-y) << std::endl;
386 OOMPH_CURRENT_FUNCTION,
387 OOMPH_EXCEPTION_LOCATION);
394 Vector<GeomObject*> geom_object_pt(1);
399 geom_object_pt[0]=geom_obj_pt;
402 Vector<double> ref_value(4);
405 ref_value[0]=r_wall[0];
410 ref_value[1]=y/r_wall[1];
422 ref_value[3]=zeta[0];
425 nod_pt->add_node_update_info(
451 template<
class ELEMENT>
453 AlgebraicNode*& node_pt)
456 Vector<double> ref_value(node_pt->vector_ref_value());
474 double zeta=ref_value[3];
477 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
484 Vector<double> zeta_wall(1);
496 GeomObject* geom_obj_pt;
497 this->
Wall_pt->locate_zeta(zeta_wall,geom_obj_pt,s);
503 geom_object_pt[0]=geom_obj_pt;
527 node_pt->kill_node_update_info();
530 node_pt->add_node_update_info(
CollapsibleChannelMesh(const unsigned &nup, const unsigned &ncollapsible, const unsigned &ndown, const unsigned &ny, const double &lup, const double &lcollapsible, const double &ldown, const double &ly, GeomObject *wall_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in upstream/collapsible/ downstream segment and across the chann...
CollapsibleChannelDomain * Domain_pt
Pointer to domain.
double l_collapsible()
Length of collapsible segment.
Collapsible channel domain.
CollapsibleChannelDomain * domain_pt()
Access function to domain.
void update_node_update(AlgebraicNode *&node_pt)
Update the node update data for specified node following any mesh adapation.
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
double l_up()
Length of upstream section.
GeomObject * Wall_pt
Pointer to geometric object that represents the moving wall.
void setup_algebraic_node_update()
Function to setup the algebraic node update.