30 #ifndef OOMPH_TWO_LAYER_SPINE_MESH_TEMPLATE_CC 31 #define OOMPH_TWO_LAYER_SPINE_MESH_TEMPLATE_CC 54 template<
class ELEMENT>
56 const unsigned &nx,
const unsigned &ny1,
const unsigned &ny2,
57 const double &lx,
const double &h1,
const double &h2,
58 TimeStepper* time_stepper_pt) :
63 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
66 MeshChecker::assert_geometric_element<SpineFiniteElement,ELEMENT>(2);
103 template<
class ELEMENT>
105 const unsigned &
nx,
const unsigned &ny1,
const unsigned &ny2,
106 const double &lx,
const double &h1,
const double &h2,
107 const bool& periodic_in_x, TimeStepper* time_stepper_pt) :
109 false,time_stepper_pt)
112 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
115 MeshChecker::assert_geometric_element<SpineFiniteElement,ELEMENT>(2);
153 template<
class ELEMENT>
155 const unsigned &
nx,
const unsigned &ny1,
const unsigned &ny2,
156 const double &lx,
const double &h1,
const double &h2,
157 const bool& periodic_in_x,
const bool&
build_mesh,
158 TimeStepper* time_stepper_pt) :
160 false,time_stepper_pt)
163 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
166 MeshChecker::assert_geometric_element<SpineFiniteElement,ELEMENT>(2);
195 template<
class ELEMENT>
198 unsigned yelement,
unsigned ynode)
201 double xstep = (this->
Xmax-this->
Xmin)/((this->
Np-1)*this->
Nx);
203 return (this->
Xmin + xstep*((this->
Np-1)*xelement + xnode));
210 template<
class ELEMENT>
213 unsigned yelement,
unsigned ynode)
223 double y1init =
Ymin;
225 double y2init =
H1 -
Ymin;
231 double y2step = (Ymax-
H1)/((n_p-1)*
Ny2);
237 return (y1init + y1step*((n_p-1)*yelement + ynode));
241 return (y2init + y2step*((n_p-1)*(yelement-
Ny1) + ynode));
249 template<
class ELEMENT>
251 TimeStepper* time_stepper_pt)
261 unsigned long n_lower = this->
Nx*
Ny1;
262 unsigned long n_upper = this->
Nx*
Ny2;
265 for(
unsigned e=0;e<n_lower;e++)
271 for(
unsigned e=n_lower;e<(n_lower+n_upper);e++)
280 unsigned count_lower=this->
Nx*(this->Ny1-1);
281 unsigned count_upper= count_lower + this->
Nx;
282 for(
unsigned e=0;e<this->
Nx;e++)
285 this->finite_element_pt(count_lower); ++count_lower;
287 this->finite_element_pt(count_upper); ++count_upper;
293 Vector<double> b_coord;
296 const double y_interface =
H1 - this->
Ymin;
299 unsigned n_boundary_node = this->nboundary_node(3);
302 for(
unsigned n=0;n<n_boundary_node;n++)
305 Node*
const nod_pt = this->boundary_node_pt(3,n);
307 if(boundary_coordinate_exists(3))
309 b_coord.resize(nod_pt->ncoordinates_on_boundary(3));
310 nod_pt->get_coordinates_on_boundary(3,b_coord);
313 this->Boundary_coordinate_exists[4]=
true;
314 this->Boundary_coordinate_exists[5]=
true;
318 nod_pt->remove_from_boundary(3);
321 double y = nod_pt->x(1);
325 this->add_boundary_node(4,nod_pt);
327 if(this->Boundary_coordinate_exists[4])
329 nod_pt->set_coordinates_on_boundary(4,b_coord);
335 this->add_boundary_node(5,nod_pt);
337 if(this->Boundary_coordinate_exists[5])
339 nod_pt->set_coordinates_on_boundary(5,b_coord);
345 this->Boundary_node_pt[3].clear();
348 n_boundary_node = this->nboundary_node(2);
351 for(
unsigned n=0;n<n_boundary_node;n++)
354 Node*
const nod_pt = this->boundary_node_pt(2,n);
356 if(this->boundary_coordinate_exists(2))
358 b_coord.resize(nod_pt->ncoordinates_on_boundary(2));
359 nod_pt->get_coordinates_on_boundary(2,b_coord);
360 this->Boundary_coordinate_exists[3]=
true;
364 nod_pt->remove_from_boundary(2);
366 this->add_boundary_node(3,nod_pt);
367 if(this->Boundary_coordinate_exists[3])
369 nod_pt->set_coordinates_on_boundary(3,b_coord);
374 this->Boundary_node_pt[2].clear();
376 std::list<Node*> nodes_to_be_removed;
379 n_boundary_node = this->nboundary_node(1);
381 for(
unsigned n=0;n<n_boundary_node;n++)
384 Node*
const nod_pt = this->boundary_node_pt(1,n);
387 double y = nod_pt->x(1);
392 if(this->boundary_coordinate_exists(1))
394 b_coord.resize(nod_pt->ncoordinates_on_boundary(1));
395 nod_pt->get_coordinates_on_boundary(1,b_coord);
396 this->Boundary_coordinate_exists[2]=
true;
402 nodes_to_be_removed.push_back(nod_pt);
405 this->add_boundary_node(2,nod_pt);
407 if(this->Boundary_coordinate_exists[2])
409 nod_pt->set_coordinates_on_boundary(2,b_coord);
416 for(std::list<Node*>::iterator it=nodes_to_be_removed.begin();
417 it!=nodes_to_be_removed.end();++it)
419 this->remove_boundary_node(1,*it);
421 nodes_to_be_removed.clear();
427 unsigned n_p =
dynamic_cast<ELEMENT*
>(finite_element_pt(0))->nnode_1d();
433 this->Boundary_coordinate_exists[6];
436 for(
unsigned e=0;e<this->
Nx;e++)
441 FiniteElement* el_pt = this->finite_element_pt(this->Nx*this->Ny1+e);
443 for(
unsigned n=n_start;n<n_p;n++)
445 Node* nod_pt = el_pt->node_pt(n);
446 this->convert_to_boundary_node(nod_pt);
447 this->add_boundary_node(6,nod_pt);
448 b_coord[0] = nod_pt->x(0);
449 nod_pt->set_coordinates_on_boundary(6,b_coord);
456 Spine_pt.reserve((n_p-1)*this->Nx);
460 Spine_pt.reserve((n_p-1)*this->Nx+1);
470 Spine* new_spine_pt=
new Spine(
H1);
471 Spine_pt.push_back(new_spine_pt);
474 SpineNode* nod_pt=element_node_pt(0,0);
477 nod_pt->spine_pt() = new_spine_pt;
479 nod_pt->fraction() = 0.0;
481 nod_pt->spine_mesh_pt() =
this;
483 nod_pt->node_update_fct_id() = 0;
487 for(
unsigned long i=0;i<
Ny1;i++)
490 for(
unsigned l1=1;l1<n_p;l1++)
493 SpineNode* nod_pt=element_node_pt(i*this->Nx,l1*n_p);
495 nod_pt->spine_pt() = new_spine_pt;
497 nod_pt->fraction() = (nod_pt->x(1)-this->
Ymin)/(
H1);
499 nod_pt->spine_mesh_pt() =
this;
501 nod_pt->node_update_fct_id() = 0;
506 for(
unsigned long i=0;i<
Ny2;i++)
509 for(
unsigned l1=1;l1<n_p;l1++)
512 SpineNode* nod_pt=element_node_pt((Ny1+i)*this->Nx,l1*n_p);
515 nod_pt->spine_pt() = new_spine_pt;
517 nod_pt->fraction() =(nod_pt->x(1)-(this->
Ymin+
H1))/(
H2);
519 nod_pt->spine_mesh_pt() =
this;
521 nod_pt->node_update_fct_id() = 1;
530 for(
unsigned long j=0;j<this->
Nx;j++)
537 if ((this->
Xperiodic)&&(j==this->Nx-1)) n_pmax=n_p-1;
539 for(
unsigned l2=1;l2<n_pmax;l2++)
542 new_spine_pt=
new Spine(
H1);
543 Spine_pt.push_back(new_spine_pt);
546 SpineNode* nod_pt=element_node_pt(j,l2);
549 nod_pt->spine_pt() = new_spine_pt;
551 nod_pt->fraction() = 0.0;
553 nod_pt->spine_mesh_pt() =
this;
555 nod_pt->node_update_fct_id() = 0;
559 for(
unsigned long i=0;i<
Ny1;i++)
562 for(
unsigned l1=1;l1<n_p;l1++)
565 SpineNode* nod_pt=element_node_pt(i*this->Nx+j,l1*n_p+l2);
567 nod_pt->spine_pt() = new_spine_pt;
569 nod_pt->fraction() = (nod_pt->x(1)-this->
Ymin)/
H1;
571 nod_pt->spine_mesh_pt() =
this;
573 nod_pt->node_update_fct_id() = 0;
578 for(
unsigned long i=0;i<
Ny2;i++)
581 for(
unsigned l1=1;l1<n_p;l1++)
584 SpineNode* nod_pt=element_node_pt((Ny1+i)*this->Nx+j,l1*n_p+l2);
587 nod_pt->spine_pt() = new_spine_pt;
589 nod_pt->fraction() = (nod_pt->x(1)-(this->
Ymin+
H1))/
H2;
591 nod_pt->spine_mesh_pt() =
this;
593 nod_pt->node_update_fct_id() = 1;
605 Spine* final_spine_pt=Spine_pt[0];
608 SpineNode* nod_pt=element_node_pt((this->Nx-1),(n_p-1));
611 nod_pt->spine_pt() = final_spine_pt;
613 nod_pt->fraction() = element_node_pt(0,0)->fraction();
615 nod_pt->spine_mesh_pt() = element_node_pt(0,0)->spine_mesh_pt();
617 nod_pt->node_update_fct_id() = element_node_pt(0,0)->node_update_fct_id();
620 for(
unsigned i=0;i<(Ny1+
Ny2);i++)
623 for(
unsigned l1=1;l1<n_p;l1++)
627 element_node_pt(i*this->Nx+(this->Nx-1),l1*n_p+(n_p-1));
630 nod_pt->spine_pt() = final_spine_pt;
632 nod_pt->fraction() = element_node_pt(i*this->Nx,l1*n_p)->fraction();
634 nod_pt->node_update_fct_id() =
635 element_node_pt(i*this->Nx,l1*n_p)->node_update_fct_id();
637 nod_pt->spine_mesh_pt() = element_node_pt(i*this->Nx,l1*n_p)
669 this->setup_boundary_element_info();
Vector< FiniteElement * > Lower_layer_element_pt
Vector of pointers to element in the upper layer.
const unsigned & nx() const
Return number of elements in x direction.
virtual void build_two_layer_mesh(TimeStepper *time_stepper_pt)
Helper function to actually build the two-layer spine mesh (called from various constructors) ...
double y_spacing_function(unsigned xelement, unsigned xnode, unsigned yelement, unsigned ynode)
The spacing function for the y co-ordinates with three regions in each fluid.
TwoLayerSpineMesh(const unsigned &nx, const unsigned &ny1, const unsigned &ny2, const double &lx, const double &h1, const double &h2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in x-direction, number of elements in y-direction in bottom and ...
unsigned Ny2
Number of elements in upper layer.
unsigned Ny1
Number of elements in lower layer.
Vector< FiniteElement * > Interface_lower_boundary_element_pt
Vector of pointers to the elements adjacent to the interface on the lower layer.
unsigned Nx
Nx: number of elements in x-direction.
Vector< FiniteElement * > Upper_layer_element_pt
Vector of pointers to element in the lower layer.
unsigned Np
Np: number of (linear) points in the element.
bool Xperiodic
Boolean variable used to determine whether the mesh is periodic in the x-direction.
double H1
Height of the lower layer.
double H2
Height of the upper layer.
void build_mesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Generic mesh construction function: contains all the hard work.
Vector< FiniteElement * > Interface_upper_boundary_element_pt
Vector of pointers to the element adjacent to the interface on the upper layer.
double Xmin
Minimum value of x coordinate.
double Ymax
Maximum value of y coordinate.
double x_spacing_function(unsigned xelement, unsigned xnode, unsigned yelement, unsigned ynode)
The spacing function for the x co-ordinates with two regions.
double Xmax
Maximum value of x coordinate.
double Ymin
Minimum value of y coordinate.