26 #ifndef OOMPH_COLLAPSIBLE_CHANNEL_MESH_TEMPLATE_CC
27 #define OOMPH_COLLAPSIBLE_CHANNEL_MESH_TEMPLATE_CC
42 template<
class ELEMENT>
45 const unsigned& ncollapsible,
46 const unsigned& ndown,
49 const double& lcollapsible,
53 TimeStepper* time_stepper_pt)
56 lup + lcollapsible + ldown,
60 Ncollapsible(ncollapsible),
66 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
71 nup, ncollapsible, ndown,
ny, lup, lcollapsible, ldown, ly,
wall_pt);
74 unsigned nmacro = (nup + ncollapsible + ndown) *
ny;
77 for (
unsigned e = 0; e < nmacro; e++)
80 FiniteElement* el_pt = this->finite_element_pt(e);
85 el_pt->set_macro_elem_pt(this->
Domain_pt->macro_element_pt(e));
103 unsigned nbound = this->nboundary();
104 for (
unsigned b = 0; b < nbound; b++)
108 this->remove_boundary_nodes(b);
113 unsigned nnod = this->nnode();
114 for (
unsigned j = 0; j < nnod; j++)
116 if (this->node_pt(j)->is_on_boundary())
118 std::ostringstream error_message;
119 error_message <<
"Node " << j <<
"is still on boundary " << std::endl;
121 throw OomphLibError(error_message.str(),
122 OOMPH_CURRENT_FUNCTION,
123 OOMPH_EXCEPTION_LOCATION);
129 this->set_nboundary(6);
132 unsigned nnode_1d = this->finite_element_pt(0)->nnode_1d();
135 Vector<double> zeta(1);
138 unsigned first_collapsible = (
ny - 1) * (nup + ncollapsible + ndown) + nup;
142 double dzeta = lcollapsible / double(ncollapsible);
146 unsigned nelem = this->nelement();
147 for (
unsigned e = 0; e < nelem; e++)
150 if (e < nup + ncollapsible + ndown)
152 for (
unsigned i = 0; i < nnode_1d; i++)
154 this->add_boundary_node(0, this->finite_element_pt(e)->node_pt(i));
158 if ((e > (
ny - 1) * (nup + ncollapsible + ndown) - 1) &&
159 (e < (
ny - 1) * (nup + ncollapsible + ndown) + nup))
161 for (
unsigned i = 0; i < nnode_1d; i++)
163 this->add_boundary_node(
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(
176 this->finite_element_pt(e)->node_pt((nnode_1d - 1) * nnode_1d + i));
179 unsigned ix = e - first_collapsible;
183 double(ix) * dzeta + double(i) * dzeta / double(nnode_1d - 1);
186 this->finite_element_pt(e)
187 ->node_pt((nnode_1d - 1) * nnode_1d + i)
188 ->set_coordinates_on_boundary(3, zeta);
193 (
ny - 1) * (nup + ncollapsible + ndown) + nup + ncollapsible - 1) &&
194 (e <
ny * (nup + ncollapsible + ndown)))
196 for (
unsigned i = 0; i < nnode_1d; i++)
198 this->add_boundary_node(
200 this->finite_element_pt(e)->node_pt((nnode_1d - 1) * nnode_1d + i));
204 if (e % (nup + ncollapsible + ndown) == 0)
206 for (
unsigned i = 0; i < nnode_1d; i++)
208 this->add_boundary_node(
209 5, this->finite_element_pt(e)->node_pt(i * nnode_1d));
213 if (e % (nup + ncollapsible + ndown) == (nup + ncollapsible + ndown) - 1)
215 for (
unsigned i = 0; i < nnode_1d; i++)
217 this->add_boundary_node(
218 1, this->finite_element_pt(e)->node_pt((i + 1) * nnode_1d - 1));
225 this->setup_boundary_element_info();
228 this->Boundary_coordinate_exists[3] =
true;
241 template<
class ELEMENT>
243 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 =
"AlgebraicCollapsibleChannelMesh::";
270 function_name +=
"algebraic_node_update()";
273 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
278 Vector<double> ref_value(node_pt->vector_ref_value());
282 double x_bottom = ref_value[0];
287 double fract = ref_value[1];
303 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
307 GeomObject* geom_obj_pt = geom_object_pt[0];
310 Vector<double> r_wall(2);
311 geom_obj_pt->position(t, s, r_wall);
314 node_pt->x(t, 0) = x_bottom + fract * (r_wall[0] - x_bottom);
315 node_pt->x(t, 1) = fract * r_wall[1];
323 template<
class ELEMENT>
327 double l_up = this->domain_pt()->l_up();
328 double l_collapsible = this->domain_pt()->l_collapsible();
331 unsigned nnod = this->nnode();
332 for (
unsigned j = 0; j < nnod; j++)
337 AlgebraicNode* nod_pt = node_pt(j);
340 double x = nod_pt->x(0);
341 double y = nod_pt->x(1);
344 if ((x >= l_up) && (x <= (l_up + l_collapsible)))
347 Vector<double> zeta(1);
358 GeomObject* geom_obj_pt;
360 this->Wall_pt->locate_zeta(zeta, geom_obj_pt, s);
363 Vector<double> r_wall(2);
364 geom_obj_pt->position(s, r_wall);
368 if ((std::fabs(r_wall[0] - x) > 1.0e-15) &&
369 (std::fabs(r_wall[1] - y) > 1.0e-15))
371 std::ostringstream error_stream;
372 error_stream <<
"Wall must be in its undeformed position when\n"
373 <<
"algebraic node update information is set up!\n "
374 <<
"x-discrepancy: " << std::fabs(r_wall[0] - x)
376 <<
"y-discrepancy: " << std::fabs(r_wall[1] - y)
379 throw OomphLibError(error_stream.str(),
380 OOMPH_CURRENT_FUNCTION,
381 OOMPH_EXCEPTION_LOCATION);
387 Vector<GeomObject*> geom_object_pt(1);
392 geom_object_pt[0] = geom_obj_pt;
395 Vector<double> ref_value(4);
398 ref_value[0] = r_wall[0];
403 ref_value[1] = y / r_wall[1];
415 ref_value[3] = zeta[0];
418 nod_pt->add_node_update_info(
this,
436 template<
class ELEMENT>
438 AlgebraicNode*& node_pt)
441 Vector<double> ref_value(node_pt->vector_ref_value());
459 double zeta = ref_value[3];
462 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
470 Vector<double> zeta_wall(1);
482 GeomObject* geom_obj_pt;
483 this->Wall_pt->locate_zeta(zeta_wall, geom_obj_pt, s);
489 geom_object_pt[0] = geom_obj_pt;
513 node_pt->kill_node_update_info();
516 node_pt->add_node_update_info(
this,
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)
Collapsible channel domain.
GeomObject *& wall_pt()
Access function to GeomObject representing wall.
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.
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.
const unsigned & ny() const
Access function for number of elements in y directions.
////////////////////////////////////////////////////////////////////// //////////////////////////////...