26 #ifndef OOMPH_FSI_DRIVEN_CAVITY_MESH_TEMPLATE_CC
27 #define OOMPH_FSI_DRIVEN_CAVITY_MESH_TEMPLATE_CC
40 template<
class ELEMENT>
46 const double& gap_fraction,
48 TimeStepper* time_stepper_pt)
52 Gap_fraction(gap_fraction),
56 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
69 unsigned nbound = this->nboundary();
70 for (
unsigned b = 0; b < nbound; b++)
74 this->remove_boundary_nodes(b);
79 unsigned nnod = this->nnode();
80 for (
unsigned j = 0; j < nnod; j++)
82 if (this->node_pt(j)->is_on_boundary())
84 std::ostringstream error_message;
85 error_message <<
"Node " << j <<
"is still on boundary " << std::endl;
87 throw OomphLibError(error_message.str(),
88 OOMPH_CURRENT_FUNCTION,
89 OOMPH_EXCEPTION_LOCATION);
95 this->set_nboundary(6);
98 unsigned nnode_1d = this->finite_element_pt(0)->nnode_1d();
101 Vector<double> zeta(1);
105 double dzeta = lx / double(
nx);
109 unsigned nelem = this->nelement();
110 for (
unsigned e = 0; e < nelem; e++)
115 for (
unsigned i = 0; i < nnode_1d; i++)
117 this->add_boundary_node(0, this->finite_element_pt(e)->node_pt(i));
121 if (e > ((
ny - 1) *
nx) - 1)
123 for (
unsigned i = 0; i < nnode_1d; i++)
125 this->add_boundary_node(
126 3, this->finite_element_pt(e)->node_pt(2 * nnode_1d + i));
129 unsigned ix = e - (
ny - 1) *
nx;
133 double(ix) * dzeta + double(i) * dzeta / double(nnode_1d - 1);
136 this->finite_element_pt(e)
137 ->node_pt(2 * nnode_1d + i)
138 ->set_coordinates_on_boundary(3, zeta);
144 for (
unsigned i = 0; i < nnode_1d; i++)
146 Node* nod_pt = this->finite_element_pt(e)->node_pt(i * nnode_1d);
151 this->add_boundary_node(4, nod_pt);
156 this->add_boundary_node(5, nod_pt);
161 if (e %
nx ==
nx - 1)
163 for (
unsigned i = 0; i < nnode_1d; i++)
166 this->finite_element_pt(e)->node_pt((i + 1) * nnode_1d - 1);
171 this->add_boundary_node(2, nod_pt);
176 this->add_boundary_node(1, nod_pt);
184 this->setup_boundary_element_info();
187 this->Boundary_coordinate_exists[3] =
true;
200 template<
class ELEMENT>
202 const unsigned& t, AlgebraicNode*& node_pt)
218 if (t > node_pt->position_time_stepper_pt()->nprev_values())
220 std::string error_message =
221 "Trying to update the nodal position at a time level";
222 error_message +=
"beyond the number of previous values in the nodes'";
223 error_message +=
"position timestepper. This seems highly suspect!";
224 error_message +=
"If you're sure the code behaves correctly";
225 error_message +=
"in your application, remove this warning ";
226 error_message +=
"or recompile with PARNOID switched off.";
228 std::string function_name =
"AlgebraicFSIDrivenCavityMesh::";
229 function_name +=
"algebraic_node_update()";
232 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
237 Vector<double> ref_value(node_pt->vector_ref_value());
241 double x_bottom = ref_value[0];
246 double fract = ref_value[1];
262 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
266 GeomObject* geom_obj_pt = geom_object_pt[0];
269 Vector<double> r_wall(2);
270 geom_obj_pt->position(t, s, r_wall);
273 node_pt->x(t, 0) = x_bottom + fract * (r_wall[0] - x_bottom);
274 node_pt->x(t, 1) = fract * r_wall[1];
282 template<
class ELEMENT>
286 unsigned nnod = this->nnode();
287 for (
unsigned j = 0; j < nnod; j++)
292 AlgebraicNode* nod_pt = node_pt(j);
295 double x = nod_pt->x(0);
296 double y = nod_pt->x(1);
299 Vector<double> zeta(1);
310 GeomObject* geom_obj_pt;
312 this->Wall_pt->locate_zeta(zeta, geom_obj_pt, s);
315 Vector<double> r_wall(2);
316 geom_obj_pt->position(s, r_wall);
320 if ((std::fabs(r_wall[0] - x) > 1.0e-15) &&
321 (std::fabs(r_wall[1] - y) > 1.0e-15))
323 std::ostringstream error_stream;
324 error_stream <<
"Wall must be in its undeformed position when\n"
325 <<
"algebraic node update information is set up!\n "
326 <<
"x-discrepancy: " << std::fabs(r_wall[0] - x)
328 <<
"y-discrepancy: " << std::fabs(r_wall[1] - y)
332 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
338 Vector<GeomObject*> geom_object_pt(1);
343 geom_object_pt[0] = geom_obj_pt;
346 Vector<double> ref_value(4);
349 ref_value[0] = r_wall[0];
354 ref_value[1] = y / r_wall[1];
366 ref_value[3] = zeta[0];
369 nod_pt->add_node_update_info(
this,
387 template<
class ELEMENT>
389 AlgebraicNode*& node_pt)
392 Vector<double> ref_value(node_pt->vector_ref_value());
410 double zeta = ref_value[3];
413 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
421 Vector<double> zeta_wall(1);
433 GeomObject* geom_obj_pt;
434 this->Wall_pt->locate_zeta(zeta_wall, geom_obj_pt, s);
440 geom_object_pt[0] = geom_obj_pt;
464 node_pt->kill_node_update_info();
467 node_pt->add_node_update_info(
this,
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
void setup_algebraic_node_update()
Function to setup the algebraic node update.
double Gap_fraction
Fraction of the gap next to moving lid, relative to the height of the domain.
FSIDrivenCavityMesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, const double &gap_fraction, GeomObject *wall_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements, number of elements, fractional height of the gap above the movi...
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.
const unsigned & nx() const
Access function for number of elements in x directions.
////////////////////////////////////////////////////////////////////// //////////////////////////////...