26 #ifndef OOMPH_CHANNEL_SPINE_MESH_TEMPLATE_CC
27 #define OOMPH_CHANNEL_SPINE_MESH_TEMPLATE_CC
47 template<
class ELEMENT>
57 TimeStepper* time_stepper_pt)
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,
113 TimeStepper* time_stepper_pt)
132 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
135 MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(2);
152 template<
class ELEMENT>
154 TimeStepper* time_stepper_pt)
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)
199 throw OomphLibError(
"Incorrect number of element pointers!",
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;
238 Vector<double> r_wall(2), zeta(1), s_wall(1);
239 GeomObject* geometric_object_pt = 0;
248 double zeta_lo = 0.0;
249 double dzeta = Lx0 / n_x0;
252 unsigned n_prev_elements = 0;
261 Spine* new_spine_pt =
new Spine(1.0);
262 new_spine_pt->spine_height_pt()->pin(0);
263 Spine_pt.push_back(new_spine_pt);
266 SpineNode* nod_pt = element_node_pt(0, 0);
268 nod_pt->spine_pt() = new_spine_pt;
270 nod_pt->fraction() = 0.0;
272 nod_pt->spine_mesh_pt() =
this;
274 nod_pt->node_update_fct_id() = 0;
283 Straight_wall_pt->locate_zeta(zeta, geometric_object_pt, s_wall);
288 Vector<double> parameters(1, s_wall[0]);
289 nod_pt->spine_pt()->set_geom_parameter(parameters);
292 Straight_wall_pt->position(s_wall, r_wall);
295 nod_pt->spine_pt()->height() = r_wall[1];
299 Vector<GeomObject*> geom_object_pt(1);
300 geom_object_pt[0] = geometric_object_pt;
303 nod_pt->spine_pt()->set_geom_object_pt(geom_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);
316 nod_pt->spine_pt() = new_spine_pt;
319 (double(i) + double(l1) / double(n_p - 1)) /
double(n_y);
321 nod_pt->spine_mesh_pt() =
this;
323 nod_pt->node_update_fct_id() = 0;
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);
341 new_spine_pt->spine_height_pt()->pin(0);
342 Spine_pt.push_back(new_spine_pt);
345 SpineNode* nod_pt = element_node_pt(j, l2);
347 nod_pt->spine_pt() = new_spine_pt;
349 nod_pt->fraction() = 0.0;
351 nod_pt->spine_mesh_pt() =
this;
353 nod_pt->node_update_fct_id() = 0;
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);
368 Vector<double> parameters(1, s_wall[0]);
369 nod_pt->spine_pt()->set_geom_parameter(parameters);
372 Straight_wall_pt->position(s_wall, r_wall);
375 nod_pt->spine_pt()->height() = r_wall[1];
379 Vector<GeomObject*> geom_object_pt(1);
380 geom_object_pt[0] = geometric_object_pt;
383 nod_pt->spine_pt()->set_geom_object_pt(geom_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);
396 nod_pt->spine_pt() = new_spine_pt;
399 (double(i) + double(l1) / double(n_p - 1)) /
double(n_y);
401 nod_pt->spine_mesh_pt() =
this;
403 nod_pt->node_update_fct_id() = 0;
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);
435 new_spine_pt->spine_height_pt()->pin(0);
436 Spine_pt.push_back(new_spine_pt);
439 SpineNode* nod_pt = element_node_pt(j, l2);
441 nod_pt->spine_pt() = new_spine_pt;
443 nod_pt->fraction() = 0.0;
445 nod_pt->spine_mesh_pt() =
this;
447 nod_pt->node_update_fct_id() = 1;
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);
462 Vector<double> parameters(1, s_wall[0]);
463 nod_pt->spine_pt()->set_geom_parameter(parameters);
466 Wall_pt->position(s_wall, r_wall);
469 nod_pt->spine_pt()->height() = r_wall[1];
473 Vector<GeomObject*> geom_object_pt(1);
474 geom_object_pt[0] = geometric_object_pt;
477 nod_pt->spine_pt()->set_geom_object_pt(geom_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);
490 nod_pt->spine_pt() = new_spine_pt;
493 (double(i) + double(l1) / double(n_p - 1)) /
double(n_y);
495 nod_pt->spine_mesh_pt() =
this;
497 nod_pt->node_update_fct_id() = 1;
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);
533 nod_pt->node_update_fct_id() = 2;
539 zeta[0] = zeta_lo + double(j - n_x0 - n_x1) * dzeta;
541 Straight_wall_pt->locate_zeta(zeta, geometric_object_pt, s_wall);
546 Vector<double> parameters(1, s_wall[0]);
547 nod_pt->spine_pt()->set_geom_parameter(parameters);
550 Straight_wall_pt->position(s_wall, r_wall);
553 nod_pt->spine_pt()->height() = r_wall[1];
557 Vector<GeomObject*> geom_object_pt(1);
558 geom_object_pt[0] = geometric_object_pt;
561 nod_pt->spine_pt()->set_geom_object_pt(geom_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);
576 new_spine_pt->spine_height_pt()->pin(0);
577 Spine_pt.push_back(new_spine_pt);
580 SpineNode* nod_pt = element_node_pt(j, l2);
582 nod_pt->spine_pt() = new_spine_pt;
584 nod_pt->fraction() = 0.0;
586 nod_pt->spine_mesh_pt() =
this;
588 nod_pt->node_update_fct_id() = 2;
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);
603 Vector<double> parameters(1, s_wall[0]);
604 nod_pt->spine_pt()->set_geom_parameter(parameters);
607 Straight_wall_pt->position(s_wall, r_wall);
610 nod_pt->spine_pt()->height() = r_wall[1];
614 Vector<GeomObject*> geom_object_pt(1);
615 geom_object_pt[0] = geometric_object_pt;
618 nod_pt->spine_pt()->set_geom_object_pt(geom_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);
631 nod_pt->spine_pt() = new_spine_pt;
634 (double(i) + double(l1) / double(n_p - 1)) /
double(n_y);
636 nod_pt->spine_mesh_pt() =
this;
638 nod_pt->node_update_fct_id() = 2;
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();
679 nod_pt->spine_mesh_pt() =
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;
703 Vector<FiniteElement*> dummy;
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...
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.
////////////////////////////////////////////////////////////////////// //////////////////////////////...