30 #ifndef OOMPH_CHANNEL_SPINE_MESH_TEMPLATE_CC 31 #define OOMPH_CHANNEL_SPINE_MESH_TEMPLATE_CC 54 template<
class ELEMENT>
65 TimeStepper* time_stepper_pt) :
67 0.0,h,false,false,time_stepper_pt),
68 Nx0(nx0), Nx1(nx1), Nx2(nx2),
69 Lx0(lx0), Lx1(lx1), Lx2(lx2),
74 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
77 MeshChecker::assert_geometric_element<SpineFiniteElement,ELEMENT>(2);
102 template<
class ELEMENT>
113 const bool& periodic_in_x,
114 TimeStepper* time_stepper_pt) :
116 periodic_in_x,false,time_stepper_pt),
122 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
125 MeshChecker::assert_geometric_element<SpineFiniteElement,ELEMENT>(2);
146 template<
class ELEMENT>
148 TimeStepper* time_stepper_pt)
155 unsigned n_x = this->
Nx;
156 unsigned n_y = this->
Ny;
157 unsigned n_x0 = this->
Nx0;
158 unsigned n_x1 = this->
Nx1;
159 unsigned n_x2 = this->
Nx2;
162 unsigned nleft=n_x0*n_y;;
166 unsigned nright=n_x2*n_y;;
168 for(
unsigned irow=0;irow<n_y;irow++)
170 for (
unsigned e=0;e<n_x0;e++)
173 this->finite_element_pt(irow*n_x+e));
175 for (
unsigned e=0;e<n_x1;e++)
178 this->finite_element_pt(irow*n_x+(n_x0+e)));
180 for (
unsigned e=0;e<n_x2;e++)
183 this->finite_element_pt(irow*n_x+(n_x0+n_x1+e)));
189 if (nelement()!=nleft+ncentre+nright)
191 throw OomphLibError(
"Incorrect number of element pointers!",
192 OOMPH_CURRENT_FUNCTION,
193 OOMPH_EXCEPTION_LOCATION);
201 unsigned n_p =
dynamic_cast<ELEMENT*
>(finite_element_pt(0))->nnode_1d();
207 nspine = (n_p-1)*n_x;
208 Spine_pt.reserve(nspine);
217 nspine = (n_p-1)*n_x+1;
218 Spine_pt.reserve(nspine);
230 Vector<double> r_wall(2), zeta(1), s_wall(1);
231 GeomObject* geometric_object_pt=0;
241 double dzeta=
Lx0/n_x0;
244 unsigned n_prev_elements=0;
253 Spine* new_spine_pt=
new Spine(1.0);
254 new_spine_pt->spine_height_pt()->pin(0);
255 Spine_pt.push_back(new_spine_pt);
258 SpineNode* nod_pt=element_node_pt(0,0);
260 nod_pt->spine_pt() = new_spine_pt;
262 nod_pt->fraction() = 0.0;
264 nod_pt->spine_mesh_pt() =
this;
266 nod_pt->node_update_fct_id()=0;
280 Vector<double> parameters(1,s_wall[0]);
281 nod_pt->spine_pt()->set_geom_parameter(parameters);
287 nod_pt->spine_pt()->height()=r_wall[1];
291 Vector<GeomObject*> geom_object_pt(1);
292 geom_object_pt[0] = geometric_object_pt;
295 nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
300 for(
unsigned long i=0;i<n_y;i++)
303 for(
unsigned l1=1;l1<n_p;l1++)
306 SpineNode* nod_pt=element_node_pt(i*n_x,l1*n_p);
308 nod_pt->spine_pt() = new_spine_pt;
310 nod_pt->fraction()=(double(i)+double(l1)/double(n_p-1))/
double(n_y);
312 nod_pt->spine_mesh_pt() =
this;
314 nod_pt->node_update_fct_id()=0;
323 for(
unsigned long j=0;j<n_x0;j++)
328 for(
unsigned l2=1;l2<n_pmax;l2++)
331 new_spine_pt=
new Spine(1.0);
332 new_spine_pt->spine_height_pt()->pin(0);
333 Spine_pt.push_back(new_spine_pt);
336 SpineNode* nod_pt=element_node_pt(j,l2);
338 nod_pt->spine_pt() = new_spine_pt;
340 nod_pt->fraction() = 0.0;
342 nod_pt->spine_mesh_pt() =
this;
344 nod_pt->node_update_fct_id()=0;
351 zeta[0] = zeta_lo + double(j)*dzeta + double(l2)*dzeta/(n_p-1.0);
358 Vector<double> parameters(1,s_wall[0]);
359 nod_pt->spine_pt()->set_geom_parameter(parameters);
365 nod_pt->spine_pt()->height()=r_wall[1];
369 Vector<GeomObject*> geom_object_pt(1);
370 geom_object_pt[0] = geometric_object_pt;
373 nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
378 for(
unsigned long i=0;i<n_y;i++)
381 for(
unsigned l1=1;l1<n_p;l1++)
384 SpineNode* nod_pt=element_node_pt(i*n_x+j,l1*n_p+l2);
386 nod_pt->spine_pt() = new_spine_pt;
388 nod_pt->fraction()=(double(i)+double(l1)/double(n_p-1))/
double(n_y);
390 nod_pt->spine_mesh_pt() =
this;
392 nod_pt->node_update_fct_id()=0;
399 n_prev_elements+=n_x0*n_y;
415 for(
unsigned long j=n_x0;j<n_x0+n_x1;j++)
420 for(
unsigned l2=1;l2<n_pmax;l2++)
423 new_spine_pt=
new Spine(1.0);
424 new_spine_pt->spine_height_pt()->pin(0);
425 Spine_pt.push_back(new_spine_pt);
428 SpineNode* nod_pt=element_node_pt(j,l2);
430 nod_pt->spine_pt() = new_spine_pt;
432 nod_pt->fraction() = 0.0;
434 nod_pt->spine_mesh_pt() =
this;
436 nod_pt->node_update_fct_id()=1;
443 zeta[0] = zeta_lo + double(j-n_x0)*dzeta + double(l2)*dzeta/(n_p-1.0);
445 Wall_pt->locate_zeta(zeta,geometric_object_pt,s_wall);
450 Vector<double> parameters(1,s_wall[0]);
451 nod_pt->spine_pt()->set_geom_parameter(parameters);
454 Wall_pt->position(s_wall,r_wall);
457 nod_pt->spine_pt()->height()=r_wall[1];
461 Vector<GeomObject*> geom_object_pt(1);
462 geom_object_pt[0] = geometric_object_pt;
465 nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
470 for(
unsigned long i=0;i<n_y;i++)
473 for(
unsigned l1=1;l1<n_p;l1++)
476 SpineNode* nod_pt=element_node_pt(i*n_x+j,l1*n_p+l2);
478 nod_pt->spine_pt() = new_spine_pt;
480 nod_pt->fraction()=(double(i)+double(l1)/double(n_p-1))/
double(n_y);
482 nod_pt->spine_mesh_pt() =
this;
484 nod_pt->node_update_fct_id()=1;
491 n_prev_elements+=n_x1*n_y;
508 for(
unsigned long j=n_x0+n_x1;j<n_x0+n_x1+n_x2;j++)
518 SpineNode* nod_pt=element_node_pt(j,0);
520 nod_pt->node_update_fct_id()=2;
526 zeta[0] = zeta_lo + double(j-n_x0-n_x1)*dzeta;
533 Vector<double> parameters(1,s_wall[0]);
534 nod_pt->spine_pt()->set_geom_parameter(parameters);
540 nod_pt->spine_pt()->height()=r_wall[1];
544 Vector<GeomObject*> geom_object_pt(1);
545 geom_object_pt[0] = geometric_object_pt;
548 nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
557 if ((this->
Xperiodic)&&(j==n_x-1)) n_pmax=n_p-1;
559 for(
unsigned l2=1;l2<n_pmax;l2++)
562 new_spine_pt=
new Spine(1.0);
563 new_spine_pt->spine_height_pt()->pin(0);
564 Spine_pt.push_back(new_spine_pt);
567 SpineNode* nod_pt=element_node_pt(j,l2);
569 nod_pt->spine_pt() = new_spine_pt;
571 nod_pt->fraction() = 0.0;
573 nod_pt->spine_mesh_pt() =
this;
575 nod_pt->node_update_fct_id()=2;
582 zeta[0] = zeta_lo + double(j-n_x0-n_x1)*dzeta + double(l2)*dzeta/(n_p-1.0);
589 Vector<double> parameters(1,s_wall[0]);
590 nod_pt->spine_pt()->set_geom_parameter(parameters);
596 nod_pt->spine_pt()->height()=r_wall[1];
600 Vector<GeomObject*> geom_object_pt(1);
601 geom_object_pt[0] = geometric_object_pt;
604 nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
609 for(
unsigned long i=0;i<n_y;i++)
612 for(
unsigned l1=1;l1<n_p;l1++)
615 SpineNode* nod_pt=element_node_pt(i*n_x+j,l1*n_p+l2);
617 nod_pt->spine_pt() = new_spine_pt;
619 nod_pt->fraction()=(double(i)+double(l1)/double(n_p-1))/
double(n_y);
621 nod_pt->spine_mesh_pt() =
this;
623 nod_pt->node_update_fct_id()=2;
630 n_prev_elements+=n_x2*n_y;
637 Spine* final_spine_pt=Spine_pt[0];
640 SpineNode* nod_pt=element_node_pt((n_x-1),(n_p-1));
643 nod_pt->spine_pt() = final_spine_pt;
645 nod_pt->fraction() = element_node_pt(0,0)->fraction();
647 nod_pt->spine_mesh_pt() = element_node_pt(0,0)->spine_mesh_pt();
650 for(
unsigned i=0;i<n_y;i++)
653 for(
unsigned l1=1;l1<n_p;l1++)
656 SpineNode* nod_pt=element_node_pt(i*n_x+(n_x-1),l1*n_p+(n_p-1));
659 nod_pt->spine_pt() = final_spine_pt;
661 nod_pt->fraction() = element_node_pt(i*n_x,l1*n_p)->fraction();
663 nod_pt->spine_mesh_pt() =
664 element_node_pt(i*n_x,l1*n_p)->spine_mesh_pt();
679 template <
class ELEMENT>
683 unsigned n_x = this->
Nx;
684 unsigned n_y = this->
Ny;
686 unsigned long Nelement = nelement();
688 unsigned long Nfluid = n_x*n_y;
690 Vector<FiniteElement *> dummy;
693 for(
unsigned long j=0;j<n_x;j++)
696 for(
unsigned long i=0;i<n_y;i++)
699 dummy.push_back(finite_element_pt(n_x*i + j));
703 dummy.push_back(finite_element_pt(Nfluid+j));
707 for(
unsigned long e=0;e<Nelement;e++)
709 Element_pt[e] = dummy[e];
unsigned Nx0
Number of elements in the left region.
unsigned long nright() const
Number of elements in right region.
void element_reorder()
Reorder the elements so we loop over them vertically first (advantageous in "wide" domains if a front...
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...
virtual void build_channel_spine_mesh(TimeStepper *time_stepper_pt)
Helper function to actually build the channel-spine mesh (called from various constructors) ...
unsigned Ny
Ny: number of elements in y-direction.
double Lx1
Length of centre region.
unsigned long ncentre() const
Number of elements in centre region.
const unsigned & ny() const
Return number of elements in y direction.
unsigned Nx
Nx: number of elements in x-direction.
unsigned Nx1
Number of elements in the centre region.
Vector< FiniteElement * > Centre_element_pt
Vector of pointers to element in the centre region.
bool Xperiodic
Boolean variable used to determine whether the mesh is periodic in the x-direction.
unsigned Ncentre_spine
Number of spines in centre region.
void build_mesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Generic mesh construction function: contains all the hard work.
GeomObject * wall_pt()
Access function to the GeomObject for upper wall.
unsigned Nx2
Number of elements in the right region.
GeomObject * Straight_wall_pt
GeomObject for the straight upper wall.
double Lx2
Length of right region.
unsigned Nleft_spine
Number of spines in left region.
unsigned long nleft() const
Number of elements in left region.
double Lx0
Length of left region.
Vector< FiniteElement * > Right_element_pt
Vector of pointers to element in the right region.
Vector< FiniteElement * > Left_element_pt
Vector of pointers to element in the left region.
unsigned Nright_spine
Number of spines in right region.
GeomObject * Wall_pt
GeomObject for upper wall.