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,
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++)
105 for (
unsigned b=0;b<nbound;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;
123 OOMPH_CURRENT_FUNCTION,
124 OOMPH_EXCEPTION_LOCATION);
139 unsigned first_collapsible=(ny-1)*(nup+ncollapsible+ndown)+nup;
143 double dzeta= lcollapsible/double(ncollapsible);
148 for (
unsigned e=0;
e<nelem;
e++)
151 if (
e<nup+ncollapsible+ndown)
153 for (
unsigned i=0;
i<nnode_1d;
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++)
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++)
178 unsigned ix=
e-first_collapsible;
181 zeta[0]=double(ix)*dzeta+double(
i)*dzeta/double(nnode_1d-1);
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++)
199 if (
e%(nup+ncollapsible+ndown)==0)
201 for (
unsigned i=0;
i<nnode_1d;
i++)
208 if (
e%(nup+ncollapsible+ndown)==(nup+ncollapsible+ndown)-1)
210 for (
unsigned i=0;
i<nnode_1d;
i++)
239 template<
class ELEMENT>
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.";
270 "AlgebraicCollapsibleChannelMesh::";
271 function_name +=
"algebraic_node_update()";
274 OOMPH_CURRENT_FUNCTION,
275 OOMPH_EXCEPTION_LOCATION);
284 double x_bottom=ref_value[0];
289 double fract=ref_value[1];
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++)
346 double x=nod_pt->
x(0);
347 double y=nod_pt->
x(1);
350 if ( (x>=l_up) && (x<=(l_up+l_collapsible)) )
375 if ((std::fabs(r_wall[0]-x)>1.0
e-15)&&(std::fabs(r_wall[1]-y)>1.0
e-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);
399 geom_object_pt[0]=geom_obj_pt;
405 ref_value[0]=r_wall[0];
410 ref_value[1]=y/r_wall[1];
422 ref_value[3]=zeta[0];
451 template<
class ELEMENT>
474 double zeta=ref_value[3];
503 geom_object_pt[0]=geom_obj_pt;
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...
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
CollapsibleChannelDomain * Domain_pt
Pointer to domain.
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 ...
A general Finite Element class.
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
double l_collapsible()
Length of collapsible segment.
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
unsigned long nelement() const
Return number of elements in the mesh.
Vector< double > & vector_ref_value()
Return vector of reference values involved in default (usually first) update function.
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.
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 algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
double & x(const unsigned &i)
Return the i-th nodal coordinate.
unsigned nboundary() const
Return number of boundaries.
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
void setup_boundary_element_info()
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
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).
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.
double l_up()
Length of upstream section.
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...
virtual unsigned nprev_values() const =0
Number of previous values available: 0 for static, 1 for BDF<1>,...
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
GeomObject * Wall_pt
Pointer to geometric object that represents the moving wall.
Vector< GeomObject * > & vector_geom_object_pt(const int &id)
Return vector of geometric objects involved in id-th update function.
void setup_algebraic_node_update()
Function to setup the algebraic node update.
void remove_boundary_nodes()
Clear all pointers to boundary nodes.