27 #ifndef OOMPH_CHANNEL_WITH_LEAFLET_MESH_TEMPLATE_CC
28 #define OOMPH_CHANNEL_WITH_LEAFLET_MESH_TEMPLATE_CC
47 template<
class ELEMENT>
52 const double& hleaflet,
54 const unsigned& nleft,
55 const unsigned& nright,
60 nright + nleft, ny1 + ny2, lright + lleft, htot, time_stepper_pt)
63 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
71 leaflet_pt, lleft, lright, hleaflet, htot, nleft, nright, ny1, ny2);
75 unsigned nmacro = (ny1 + ny2) * (nleft + nright);
78 for (
unsigned e = 0;
e < nmacro;
e++)
101 for (
unsigned e = 0;
e < nleft;
e++)
103 for (
unsigned i = 0;
i < nnode_1d;
i++)
107 if (
e != nleft - 1 ||
i != 2)
114 for (
unsigned e = nleft;
e < nleft + nright;
e++)
116 for (
unsigned i = 0;
i < nnode_1d;
i++)
127 for (
unsigned k = 0; k < ny1; k++)
129 unsigned e = (nleft + nright) * k + nleft - 1;
130 for (
unsigned i = 0;
i < nnode_1d;
i++)
138 zeta[0] = double(k) * hleaflet / double(ny1) +
139 double(
i) * hleaflet / double(ny1) / double(nnode_1d - 1);
157 unsigned e = nleft - 1;
165 for (
unsigned i = 0;
i < nnode_1d;
i++)
168 (
i + 1) * nnode_1d - 1, time_stepper_pt);
176 zeta[0] =
i * hleaflet / double(ny1) / double(nnode_1d - 1);
182 for (
unsigned k = 1; k < ny1; k++)
184 e = (nleft + nright) * k + nleft - 1;
190 zeta[0] = k * hleaflet / double(ny1);
194 for (
unsigned i = 1;
i < nnode_1d;
i++)
197 if ((k == ny1 - 1) && (
i == nnode_1d - 1))
206 (
i + 1) * nnode_1d - 1, time_stepper_pt);
213 zeta[0] = double(k) * hleaflet / double(ny1) +
214 double(
i) * hleaflet / double(ny1) / double(nnode_1d - 1);
241 template<
class ELEMENT>
245 double hleaflet = this->domain_pt()->hleaflet();
246 double htot = this->domain_pt()->htot();
247 double lleft = this->domain_pt()->lleft();
248 double lright = this->domain_pt()->lright();
251 unsigned nnod = this->nnode();
252 for (
unsigned j = 0; j < nnod; j++)
258 double x = nod_pt->
x(0);
259 double y = nod_pt->
x(1);
266 this->Leaflet_pt->position(zeta, r);
267 if ((r[0] != X_0) || (r[1] != hleaflet))
269 std::ostringstream error_stream;
270 error_stream <<
"Wall must be in its undeformed position when\n"
271 <<
"algebraic node update information is set up!\n "
272 << r[0] <<
" " << X_0 <<
" " << r[1] <<
" " << hleaflet
275 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
283 if ((x <= X_0) && (y <= hleaflet))
292 ref_value[3] = zeta[0];
297 this->Leaflet_pt->locate_zeta(zeta, geom_obj_pt,
s);
301 geom_object_pt[0] = geom_obj_pt;
309 ref_value[2] = (lleft + x - X_0) / lleft;
320 if ((x >= X_0) && (y <= hleaflet))
329 ref_value[3] = zeta[0];
334 this->Leaflet_pt->locate_zeta(zeta, geom_obj_pt,
s);
338 geom_object_pt[0] = geom_obj_pt;
346 ref_value[2] = (x - X_0) / lright;
356 if ((x <= X_0) && (y >= hleaflet))
362 ref_value[1] = (y - hleaflet) / (htot - hleaflet);
366 ref_value[2] = (lleft + x - X_0) / lleft;
370 geom_object_pt[0] = this->Leaflet_pt;
380 if ((x >= X_0) && (y >= hleaflet))
386 ref_value[1] = (y - hleaflet) / (htot - hleaflet);
390 ref_value[2] = (x - X_0) / lright;
394 geom_object_pt[0] = this->Leaflet_pt;
411 template<
class ELEMENT>
420 node_update_I(
t, node_pt);
424 node_update_II(
t, node_pt);
428 node_update_III(
t, node_pt);
432 node_update_IV(
t, node_pt);
436 std::ostringstream error_message;
437 error_message <<
"The node update fct id is " <<
id
438 <<
", but it should only be one of " << 1 <<
", " << 2
439 <<
", " << 3 <<
" or " << 4 << std::endl;
441 "AlgebraicChannelWithLeafletMesh::algebraic_node_update()";
444 OOMPH_CURRENT_FUNCTION,
445 OOMPH_EXCEPTION_LOCATION);
454 template<
class ELEMENT>
459 double lleft = this->domain_pt()->lleft();
472 double y0 = ref_value[0];
473 double x0 = -lleft + X_0;
487 double r = ref_value[2];
491 node_pt->
x(
t, 0) = x0 + r * (r_wall[0] - x0);
492 node_pt->
x(
t, 1) = y0 + r * (r_wall[1] - y0);
499 template<
class ELEMENT>
504 double lright = this->domain_pt()->lright();
517 double y0 = ref_value[0];
518 double x0 = X_0 + lright;
530 double r = ref_value[2];
533 node_pt->
x(
t, 0) = r_wall[0] + r * (x0 - r_wall[0]);
534 node_pt->
x(
t, 1) = r_wall[1] + r * (y0 - r_wall[1]);
541 template<
class ELEMENT>
547 double htot = this->domain_pt()->htot();
554 this->Leaflet_pt->position(
t, xi, r_join);
556 r[0] = r_join[0] + zeta[0] * (X_0 - r_join[0]);
557 r[1] = r_join[1] + zeta[0] * (htot - r_join[1]);
563 template<
class ELEMENT>
568 double lleft = this->domain_pt()->lleft();
575 double y0 = ref_value[0];
576 double x0 = -lleft + X_0;
583 slanted_bound_up(
t,
s, r_line);
587 double r = ref_value[2];
590 node_pt->
x(
t, 0) = x0 + r * (r_line[0] - x0);
591 node_pt->
x(
t, 1) = y0 + r * (r_line[1] - y0);
597 template<
class ELEMENT>
602 double lright = this->domain_pt()->lright();
609 double y0 = ref_value[0];
610 double x0 = X_0 + lright;
618 slanted_bound_up(
t,
s, r_line);
622 double r = ref_value[2];
625 node_pt->
x(
t, 0) = r_line[0] + r * (x0 - r_line[0]);
626 node_pt->
x(
t, 1) = r_line[1] + r * (y0 - r_line[1]);
638 template<
class ELEMENT>
645 if ((
id == 1) || (
id == 2))
652 zeta_wall[0] = ref_value[3];
657 this->Leaflet_pt->
locate_zeta(zeta_wall, geom_obj_pt,
s);
666 geom_object_pt[0] = geom_obj_pt;
void setup_algebraic_node_update()
Function to setup the algebraic node update.
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
void node_update_I(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in lower left region (I)
void node_update_III(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in upper left region (III)
void node_update_II(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in lower right region (II)
void slanted_bound_up(const unsigned &t, const Vector< double > &zeta, Vector< double > &r)
Helper function.
void node_update_IV(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in upper right region (IV)
////////////////////////////////////////////////////////////////////
int node_update_fct_id()
Default (usually first if there are multiple ones) node update fct id.
void kill_node_update_info(const int &id=0)
Erase algebraic node update information for id-th node update function. Id defaults to 0.
Vector< GeomObject * > & vector_geom_object_pt(const int &id)
Return vector of geometric objects involved in id-th update function.
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 ...
Vector< double > & vector_ref_value()
Return vector of reference values involved in default (usually first) update function.
Rectangular domain with a leaflet blocking the lower half.
ChannelWithLeafletDomain * Domain_pt
Pointer to domain.
GeomObject * Leaflet_pt
Pointer to GeomObject that represents the leaflet.
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...
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
A general Finite Element class.
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.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overload...
virtual Node * construct_boundary_node(const unsigned &n)
Construct the local node n as a boundary node; that is a node that MAY be placed on a mesh boundary a...
/////////////////////////////////////////////////////////////////////
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
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...
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
std::vector< bool > Boundary_coordinate_exists
Vector of boolean data that indicates whether the boundary coordinates have been set for the boundary...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
void remove_boundary_nodes()
Clear all pointers to boundary nodes.
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(....
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_node_pt(Node *const &node_pt)
Add a (pointer to a) node to the mesh.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
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...
An OomphLibError object which should be thrown when an run-time error is encountered....
void setup_boundary_element_info()
Setup lookup schemes which establish whic elements are located next to mesh's boundaries (wrapper to ...
void update_node_update(AlgebraicNode *&node_pt)
Update the node update data for specified node following any mesh adapation.
Simple rectangular 2D Quad mesh class. Nx : number of elements in the x direction.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...