30 #ifndef OOMPH_TUBE_MESH_TEMPLATE_CC 31 #define OOMPH_TUBE_MESH_TEMPLATE_CC 45 template <
class ELEMENT>
50 const unsigned& nlayer,
55 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(3);
68 unsigned nelem=5*nlayer;
72 ELEMENT* dummy_el_pt=
new ELEMENT;
75 unsigned n_p = dummy_el_pt->nnode_1d();
81 unsigned nnodes_total=
82 (n_p*n_p + 4*(n_p-1)*(n_p -1))*(1+nlayer*(n_p-1));
92 for (
unsigned ielem=0;ielem<nelem;ielem++)
98 for (
unsigned i2=0;i2<n_p;i2++)
101 for (
unsigned i1=0;i1<n_p;i1++)
104 for (
unsigned i0=0;i0<n_p;i0++)
107 unsigned jnod_local=i0+i1*n_p+i2*n_p*n_p;
111 construct_node(jnod_local,time_stepper_pt);
114 s[0]=-1.0+2.0*double(i0)/double(n_p-1);
115 s[1]=-1.0+2.0*double(i1)/double(n_p-1);
116 s[2]=-1.0+2.0*double(i2)/double(n_p-1);
117 Domain_pt->macro_element_pt(ielem)->macro_map(s,r);
119 node_pt->
x(0) = r[0];
120 node_pt->
x(1) = r[1];
121 node_pt->
x(2) = r[2];
128 unsigned node_count=0;
131 double node_kill_tol=1.0e-12;
140 for (
unsigned ielem=0;ielem<nelem;ielem++)
144 unsigned ilayer=unsigned(ielem/5);
155 for (
unsigned i2=0;i2<n_p;i2++)
159 for (
unsigned i1=0;i1<n_p;i1++)
163 for (
unsigned i0=0;i0<n_p;i0++)
167 unsigned jnod_local=i0+i1*n_p+i2*n_p*n_p;
174 if ((i2==0)&&(ilayer>0))
177 unsigned ielem_neigh=ielem-5;
180 unsigned i0_neigh=i0;
181 unsigned i1_neigh=i1;
182 unsigned i2_neigh=n_p-1;
183 unsigned jnod_local_neigh=i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
186 for (
unsigned i=0;
i<3;
i++)
188 double error=std::fabs(
192 if (error>node_kill_tol)
195 <<
i <<
" " << error << std::endl;
218 if ((i2==0)&&(ilayer==0))
225 if ((i2==n_p-1)&&(ilayer==nlayer-1))
249 for (
unsigned i2=0;i2<n_p;i2++)
253 for (
unsigned i1=0;i1<n_p;i1++)
257 for (
unsigned i0=0;i0<n_p;i0++)
261 unsigned jnod_local=i0+i1*n_p+i2*n_p*n_p;
268 if ((i2==0)&&(ilayer>0))
271 unsigned ielem_neigh=ielem-5;
274 unsigned i0_neigh=i0;
275 unsigned i1_neigh=i1;
276 unsigned i2_neigh=n_p-1;
277 unsigned jnod_local_neigh=i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
281 for (
unsigned i=0;
i<3;
i++)
283 double error=std::fabs(
287 if (error>node_kill_tol)
290 <<
i <<
" " << error << std::endl;
312 unsigned ielem_neigh=ielem-1;
315 unsigned i0_neigh=i0;
317 unsigned i2_neigh=i2;
318 unsigned jnod_local_neigh
319 =i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
322 for (
unsigned i=0;
i<3;
i++)
324 double error=std::fabs(
328 if (error>node_kill_tol)
331 <<
i <<
" " << error << std::endl;
355 if ((i2==0)&&(ilayer==0))
362 if ((i2==n_p-1)&&(ilayer==nlayer-1))
375 zeta[0]=centreline_limits[0]+
376 (double(ilayer)+double(i2)/double(n_p-1))*
377 (centreline_limits[1]-centreline_limits[0])/double(nlayer);
380 zeta[1]= theta_positions[0] +
381 double(i1)/double(n_p-1)*0.5*
382 (theta_positions[1]-theta_positions[0]);
384 Node_pt[node_count]->set_coordinates_on_boundary(1,zeta);
402 for (
unsigned i2=0;i2<n_p;i2++)
406 for (
unsigned i1=0;i1<n_p;i1++)
410 for (
unsigned i0=0;i0<n_p;i0++)
414 unsigned jnod_local=i0+i1*n_p+i2*n_p*n_p;
421 if ((i2==0)&&(ilayer>0))
425 unsigned ielem_neigh=ielem-5;
428 unsigned i0_neigh=i0;
429 unsigned i1_neigh=i1;
430 unsigned i2_neigh=n_p-1;
431 unsigned jnod_local_neigh=i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
434 for (
unsigned i=0;
i<3;
i++)
436 double error=std::fabs(
440 if (error>node_kill_tol)
443 <<
i <<
" " << error << std::endl;
466 unsigned ielem_neigh=ielem-1;
469 unsigned i0_neigh=n_p-1;
470 unsigned i1_neigh= n_p-1 - i0;
471 unsigned i2_neigh=i2;
472 unsigned jnod_local_neigh
473 =i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
476 for (
unsigned i=0;
i<3;
i++)
478 double error=std::fabs(
482 if (error>node_kill_tol)
485 <<
i <<
" " << error << std::endl;
502 if ((i0==0)&&(i1!=0))
506 unsigned ielem_neigh=ielem-2;
509 unsigned i0_neigh=n_p-1;
510 unsigned i1_neigh=i1;
511 unsigned i2_neigh=i2;
512 unsigned jnod_local_neigh
513 = i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
516 for (
unsigned i=0;
i<3;
i++)
518 double error=std::fabs(
522 if (error>node_kill_tol)
525 <<
i <<
" " << error << std::endl;
549 if ((i2==0)&&(ilayer==0))
556 if ((i2==n_p-1)&&(ilayer==nlayer-1))
569 zeta[0]=centreline_limits[0]+
570 (double(ilayer)+double(i2)/double(n_p-1))*
571 (centreline_limits[1]-centreline_limits[0])/double(nlayer);
574 zeta[1]=theta_positions[1] +
575 double(i1)/double(n_p-1)*0.5*
576 (theta_positions[2]-theta_positions[1]);
578 Node_pt[node_count]->set_coordinates_on_boundary(1,zeta);
598 for (
unsigned i2=0;i2<n_p;i2++)
602 for (
unsigned i1=0;i1<n_p;i1++)
606 for (
unsigned i0=0;i0<n_p;i0++)
610 unsigned jnod_local=i0+i1*n_p+i2*n_p*n_p;
617 if ((i2==0)&&(ilayer>0))
621 unsigned ielem_neigh=ielem-5;
624 unsigned i0_neigh=i0;
625 unsigned i1_neigh=i1;
626 unsigned i2_neigh=n_p-1;
627 unsigned jnod_local_neigh=
628 i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
631 for (
unsigned i=0;
i<3;
i++)
633 double error=std::fabs(
637 if (error>node_kill_tol)
640 <<
i <<
" " << error << std::endl;
663 unsigned ielem_neigh=ielem-1;
666 unsigned i0_neigh=i1;
667 unsigned i1_neigh= n_p-1;
668 unsigned i2_neigh=i2;
669 unsigned jnod_local_neigh
670 =i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
673 for (
unsigned i=0;
i<3;
i++)
675 double error=std::fabs(
679 if (error>node_kill_tol)
682 <<
i <<
" " << error << std::endl;
698 if ((i1==0)&&(i0!=n_p-1))
702 unsigned ielem_neigh=ielem-3;
705 unsigned i0_neigh=i0;
706 unsigned i1_neigh=n_p-1;
707 unsigned i2_neigh=i2;
708 unsigned jnod_local_neigh
709 = i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
712 for (
unsigned i=0;
i<3;
i++)
714 double error=std::fabs(
718 if (error>node_kill_tol)
721 <<
i <<
" " << error << std::endl;
745 if ((i2==0)&&(ilayer==0))
752 if ((i2==n_p-1)&&(ilayer==nlayer-1))
765 zeta[0]=centreline_limits[0]+
766 (double(ilayer)+double(i2)/double(n_p-1))*
767 (centreline_limits[1]-centreline_limits[0])/double(nlayer);
770 zeta[1]=theta_positions[3] +
771 double(i0)/double(n_p-1)*0.5*
772 (theta_positions[2]-theta_positions[3]);
774 Node_pt[node_count]->set_coordinates_on_boundary(1,zeta);
794 for (
unsigned i2=0;i2<n_p;i2++)
798 for (
unsigned i1=0;i1<n_p;i1++)
802 for (
unsigned i0=0;i0<n_p;i0++)
806 unsigned jnod_local=i0+i1*n_p+i2*n_p*n_p;
813 if ((i2==0)&&(ilayer>0))
817 unsigned ielem_neigh=ielem-5;
820 unsigned i0_neigh=i0;
821 unsigned i1_neigh=i1;
822 unsigned i2_neigh=n_p-1;
823 unsigned jnod_local_neigh=
824 i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
827 for (
unsigned i=0;
i<3;
i++)
829 double error=std::fabs(
833 if (error>node_kill_tol)
836 <<
i <<
" " << error << std::endl;
859 unsigned ielem_neigh=ielem-1;
863 unsigned i1_neigh= n_p - 1 -i0;
864 unsigned i2_neigh=i2;
865 unsigned jnod_local_neigh
866 =i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
869 for (
unsigned i=0;
i<3;
i++)
871 double error=std::fabs(
875 if (error>node_kill_tol)
878 <<
i <<
" " << error << std::endl;
894 if ((i0==n_p-1)&&(i1!=n_p-1))
898 unsigned ielem_neigh=ielem-4;
902 unsigned i1_neigh=i1;
903 unsigned i2_neigh=i2;
904 unsigned jnod_local_neigh
905 = i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
908 for (
unsigned i=0;
i<3;
i++)
910 double error=std::fabs(
914 if (error>node_kill_tol)
917 <<
i <<
" " << error << std::endl;
933 if ((i1==0)&&(i0!=n_p-1))
937 unsigned ielem_neigh=ielem-3;
941 unsigned i1_neigh=i0;
942 unsigned i2_neigh=i2;
943 unsigned jnod_local_neigh
944 = i0_neigh+i1_neigh*n_p+i2_neigh*n_p*n_p;
947 for (
unsigned i=0;
i<3;
i++)
949 double error=std::fabs(
953 if (error>node_kill_tol)
956 <<
i <<
" " << error << std::endl;
981 if ((i2==0)&&(ilayer==0))
988 if ((i2==n_p-1)&&(ilayer==nlayer-1))
1001 zeta[0]=centreline_limits[0]+
1002 (double(ilayer)+double(i2)/double(n_p-1))*
1003 (centreline_limits[1]-centreline_limits[0])/double(nlayer);
1006 zeta[1]=theta_positions[0] + 2.0*pi +
1007 double(i1)/double(n_p-1)*0.5*
1008 (theta_positions[3]-theta_positions[0] + 2.0*pi);
1010 Node_pt[node_count]->set_coordinates_on_boundary(1,zeta);
1029 std::ostringstream error_stream;
1030 error_stream <<
"Error in killing nodes\n" 1031 <<
"The most probable cause is that the domain is not\n" 1032 <<
"compatible with the mesh.\n" 1033 <<
"For the TubeMesh, the domain must be\n" 1034 <<
"topologically consistent with a quarter tube with a\n" 1035 <<
"non-curved centreline.\n";
1037 OOMPH_CURRENT_FUNCTION,
1038 OOMPH_EXCEPTION_LOCATION);
void setup_boundary_element_info()
Vector< Node * > Node_pt
Vector of pointers to nodes.
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement *> &finite_element_pt)
A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this...
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
TubeMesh(GeomObject *wall_pt, const Vector< double > ¢reline_limits, const Vector< double > &theta_positions, const Vector< double > &radius_box, const unsigned &nlayer, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object that specifies the volume, start and end coordinates fo...
std::vector< bool > Boundary_coordinate_exists
Vector of boolean data that indicates whether the boundary coordinates have been set for the boundary...
const double Pi
50 digits from maple
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Tube as a domain. The entire domain must be defined by a GeomObject with the following convention: ze...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
TubeDomain * Domain_pt
Pointer to domain.
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...