26 #ifndef OOMPH_CHANNEL_SPINE_MESH_TEMPLATE_CC
27 #define OOMPH_CHANNEL_SPINE_MESH_TEMPLATE_CC
47 template<
class ELEMENT>
76 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
79 MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(2);
102 template<
class ELEMENT>
112 const bool& periodic_in_x,
132 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
135 MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(2);
152 template<
class ELEMENT>
161 unsigned n_x = this->Nx;
162 unsigned n_y = this->Ny;
163 unsigned n_x0 = this->Nx0;
164 unsigned n_x1 = this->Nx1;
165 unsigned n_x2 = this->Nx2;
168 unsigned nleft = n_x0 * n_y;
170 Left_element_pt.reserve(nleft);
171 unsigned ncentre = n_x1 * n_y;
173 Centre_element_pt.reserve(ncentre);
174 unsigned nright = n_x2 * n_y;
176 Right_element_pt.reserve(nright);
177 for (
unsigned irow = 0; irow < n_y; irow++)
179 for (
unsigned e = 0;
e < n_x0;
e++)
181 Left_element_pt.push_back(this->finite_element_pt(irow * n_x +
e));
183 for (
unsigned e = 0;
e < n_x1;
e++)
185 Centre_element_pt.push_back(
186 this->finite_element_pt(irow * n_x + (n_x0 +
e)));
188 for (
unsigned e = 0;
e < n_x2;
e++)
190 Right_element_pt.push_back(
191 this->finite_element_pt(irow * n_x + (n_x0 + n_x1 +
e)));
197 if (nelement() != nleft + ncentre + nright)
200 OOMPH_CURRENT_FUNCTION,
201 OOMPH_EXCEPTION_LOCATION);
209 unsigned n_p =
dynamic_cast<ELEMENT*
>(finite_element_pt(0))->nnode_1d();
215 nspine = (n_p - 1) * n_x;
216 Spine_pt.reserve(nspine);
219 Nleft_spine = (n_p - 1) * n_x0 + 1;
220 Ncentre_spine = (n_p - 1) * n_x1 + 1;
221 Nright_spine = (n_p - 1) * n_x2;
225 nspine = (n_p - 1) * n_x + 1;
226 Spine_pt.reserve(nspine);
229 Nleft_spine = (n_p - 1) * n_x0 + 1;
230 Ncentre_spine = (n_p - 1) * n_x1 + 1;
231 Nright_spine = (n_p - 1) * n_x2 + 1;
248 double zeta_lo = 0.0;
249 double dzeta = Lx0 / n_x0;
252 unsigned n_prev_elements = 0;
263 Spine_pt.push_back(new_spine_pt);
266 SpineNode* nod_pt = element_node_pt(0, 0);
283 Straight_wall_pt->locate_zeta(zeta, geometric_object_pt, s_wall);
292 Straight_wall_pt->position(s_wall, r_wall);
300 geom_object_pt[0] = geometric_object_pt;
308 for (
unsigned long i = 0;
i < n_y;
i++)
311 for (
unsigned l1 = 1; l1 < n_p; l1++)
314 SpineNode* nod_pt = element_node_pt(
i * n_x, l1 * n_p);
319 (double(
i) + double(l1) / double(n_p - 1)) /
double(n_y);
332 for (
unsigned long j = 0; j < n_x0; j++)
336 unsigned n_pmax = n_p;
337 for (
unsigned l2 = 1; l2 < n_pmax; l2++)
340 new_spine_pt =
new Spine(1.0);
342 Spine_pt.push_back(new_spine_pt);
345 SpineNode* nod_pt = element_node_pt(j, l2);
361 zeta_lo + double(j) * dzeta + double(l2) * dzeta / (n_p - 1.0);
363 Straight_wall_pt->locate_zeta(zeta, geometric_object_pt, s_wall);
372 Straight_wall_pt->position(s_wall, r_wall);
380 geom_object_pt[0] = geometric_object_pt;
388 for (
unsigned long i = 0;
i < n_y;
i++)
391 for (
unsigned l1 = 1; l1 < n_p; l1++)
394 SpineNode* nod_pt = element_node_pt(
i * n_x + j, l1 * n_p + l2);
399 (double(
i) + double(l1) / double(n_p - 1)) /
double(n_y);
410 n_prev_elements += n_x0 * n_y;
426 for (
unsigned long j = n_x0; j < n_x0 + n_x1; j++)
430 unsigned n_pmax = n_p;
431 for (
unsigned l2 = 1; l2 < n_pmax; l2++)
434 new_spine_pt =
new Spine(1.0);
436 Spine_pt.push_back(new_spine_pt);
439 SpineNode* nod_pt = element_node_pt(j, l2);
454 zeta[0] = zeta_lo + double(j - n_x0) * dzeta +
455 double(l2) * dzeta / (n_p - 1.0);
457 Wall_pt->locate_zeta(zeta, geometric_object_pt, s_wall);
466 Wall_pt->position(s_wall, r_wall);
474 geom_object_pt[0] = geometric_object_pt;
482 for (
unsigned long i = 0;
i < n_y;
i++)
485 for (
unsigned l1 = 1; l1 < n_p; l1++)
488 SpineNode* nod_pt = element_node_pt(
i * n_x + j, l1 * n_p + l2);
493 (double(
i) + double(l1) / double(n_p - 1)) /
double(n_y);
504 n_prev_elements += n_x1 * n_y;
521 for (
unsigned long j = n_x0 + n_x1; j < n_x0 + n_x1 + n_x2; j++)
529 if (j == n_x0 + n_x1)
531 SpineNode* nod_pt = element_node_pt(j, 0);
539 zeta[0] = zeta_lo + double(j - n_x0 - n_x1) * dzeta;
541 Straight_wall_pt->locate_zeta(zeta, geometric_object_pt, s_wall);
550 Straight_wall_pt->position(s_wall, r_wall);
558 geom_object_pt[0] = geometric_object_pt;
569 unsigned n_pmax = n_p;
570 if ((this->Xperiodic) && (j == n_x - 1)) n_pmax = n_p - 1;
572 for (
unsigned l2 = 1; l2 < n_pmax; l2++)
575 new_spine_pt =
new Spine(1.0);
577 Spine_pt.push_back(new_spine_pt);
580 SpineNode* nod_pt = element_node_pt(j, l2);
595 zeta[0] = zeta_lo + double(j - n_x0 - n_x1) * dzeta +
596 double(l2) * dzeta / (n_p - 1.0);
598 Straight_wall_pt->locate_zeta(zeta, geometric_object_pt, s_wall);
607 Straight_wall_pt->position(s_wall, r_wall);
615 geom_object_pt[0] = geometric_object_pt;
623 for (
unsigned long i = 0;
i < n_y;
i++)
626 for (
unsigned l1 = 1; l1 < n_p; l1++)
629 SpineNode* nod_pt = element_node_pt(
i * n_x + j, l1 * n_p + l2);
634 (double(
i) + double(l1) / double(n_p - 1)) /
double(n_y);
645 n_prev_elements += n_x2 * n_y;
652 Spine* final_spine_pt = Spine_pt[0];
655 SpineNode* nod_pt = element_node_pt((n_x - 1), (n_p - 1));
658 nod_pt->
spine_pt() = final_spine_pt;
660 nod_pt->
fraction() = element_node_pt(0, 0)->fraction();
662 nod_pt->
spine_mesh_pt() = element_node_pt(0, 0)->spine_mesh_pt();
665 for (
unsigned i = 0;
i < n_y;
i++)
668 for (
unsigned l1 = 1; l1 < n_p; l1++)
672 element_node_pt(
i * n_x + (n_x - 1), l1 * n_p + (n_p - 1));
675 nod_pt->
spine_pt() = final_spine_pt;
677 nod_pt->
fraction() = element_node_pt(
i * n_x, l1 * n_p)->fraction();
680 element_node_pt(
i * n_x, l1 * n_p)->spine_mesh_pt();
693 template<
class ELEMENT>
696 unsigned n_x = this->Nx;
697 unsigned n_y = this->Ny;
699 unsigned long Nelement = nelement();
701 unsigned long Nfluid = n_x * n_y;
706 for (
unsigned long j = 0; j < n_x; j++)
709 for (
unsigned long i = 0;
i < n_y;
i++)
712 dummy.push_back(finite_element_pt(n_x *
i + j));
716 dummy.push_back(finite_element_pt(Nfluid + j));
720 for (
unsigned long e = 0;
e < Nelement;
e++)
722 Element_pt[
e] = dummy[
e];
virtual void build_channel_spine_mesh(TimeStepper *time_stepper_pt)
Helper function to actually build the channel-spine mesh (called from various constructors)
GeomObject * Straight_wall_pt
GeomObject for the straight upper wall.
ChannelSpineMesh(const unsigned &nx0, const unsigned &nx1, const unsigned &nx2, const unsigned &ny, const double &lx0, const double &lx1, const double &lx2, const double &h, GeomObject *wall_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in x-direction in regions 0,1 and 2, number of elements in y-dir...
void element_reorder()
Reorder the elements so we loop over them vertically first (advantageous in "wide" domains if a front...
void pin(const unsigned &i)
Pin the i-th stored variable.
/////////////////////////////////////////////////////////////////////
An OomphLibError object which should be thrown when an run-time error is encountered....
RectangularQuadMesh is a two-dimensional mesh of Quad elements with Nx elements in the "x" (horizonal...
void build_mesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Generic mesh construction function: contains all the hard work.
Class for nodes that live on spines. The assumption is that each Node lies at a fixed fraction on a s...
SpineMesh *& spine_mesh_pt()
Access function to Pointer to SpineMesh that this node is a part of and which implements the node upd...
Spine *& spine_pt()
Access function to spine.
unsigned & node_update_fct_id()
Access function to ID of node update function (within specific mesh)
double & fraction()
Set reference to fraction along spine.
Spines are used for algebraic node update operations in free-surface fluid problems: They form the ba...
void set_geom_object_pt(const Vector< GeomObject * > &geom_object_pt)
Set vector of (pointers to) geometric objects that is involved in the node update operations for this...
void set_geom_parameter(const Vector< double > &geom_parameter)
Set vector of geometric parameters that are involved in the node update operations for this Spine....
double & height()
Access function to spine height.
Data *& spine_height_pt()
Access function to Data object that stores the spine height.
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////// //////////////////////////////...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...