30 #ifndef OOMPH_TUBE_MESH_TEMPLATE_CC 31 #define OOMPH_TUBE_MESH_TEMPLATE_CC 45 template <
class ELEMENT>
47 const Vector<double> ¢reline_limits,
48 const Vector<double> &theta_positions,
49 const Vector<double> &radius_box,
50 const unsigned& nlayer,
51 TimeStepper* time_stepper_pt) :
55 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(3);
65 Boundary_coordinate_exists[1] =
true;
68 unsigned nelem=5*nlayer;
69 Element_pt.resize(nelem);
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));
83 Node_pt.resize(nnodes_total);
89 Vector<double> zeta(2);
92 for (
unsigned ielem=0;ielem<nelem;ielem++)
95 Element_pt[ielem] =
new ELEMENT;
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;
110 Node* node_pt=finite_element_pt(ielem)->
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;
137 const double pi = MathematicalConstants::Pi;
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(
189 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
190 finite_element_pt(ielem_neigh)->
191 node_pt(jnod_local_neigh)->x(i));
192 if (error>node_kill_tol)
194 oomph_info <<
"Error in node killing for i " 195 << i <<
" " << error << std::endl;
201 delete finite_element_pt(ielem)->node_pt(jnod_local);
205 finite_element_pt(ielem)->node_pt(jnod_local)=
206 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
213 Node_pt[node_count]=finite_element_pt(ielem)->node_pt(jnod_local);
218 if ((i2==0)&&(ilayer==0))
220 this->convert_to_boundary_node(Node_pt[node_count]);
221 add_boundary_node(0,Node_pt[node_count]);
225 if ((i2==n_p-1)&&(ilayer==nlayer-1))
227 this->convert_to_boundary_node(Node_pt[node_count]);
228 add_boundary_node(2,Node_pt[node_count]);
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(
284 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
285 finite_element_pt(ielem_neigh)->
286 node_pt(jnod_local_neigh)->x(i));
287 if (error>node_kill_tol)
289 oomph_info <<
"Error in node killing for i " 290 << i <<
" " << error << std::endl;
296 delete finite_element_pt(ielem)->node_pt(jnod_local);
300 finite_element_pt(ielem)->node_pt(jnod_local)=
301 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
325 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
326 finite_element_pt(ielem_neigh)->
327 node_pt(jnod_local_neigh)->x(i));
328 if (error>node_kill_tol)
330 oomph_info <<
"Error in node killing for i " 331 << i <<
" " << error << std::endl;
337 delete finite_element_pt(ielem)->node_pt(jnod_local);
341 finite_element_pt(ielem)->node_pt(jnod_local)=
342 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
350 finite_element_pt(ielem)->node_pt(jnod_local);
355 if ((i2==0)&&(ilayer==0))
357 this->convert_to_boundary_node(Node_pt[node_count]);
358 add_boundary_node(0,Node_pt[node_count]);
362 if ((i2==n_p-1)&&(ilayer==nlayer-1))
364 this->convert_to_boundary_node(Node_pt[node_count]);
365 add_boundary_node(2,Node_pt[node_count]);
371 this->convert_to_boundary_node(Node_pt[node_count]);
372 add_boundary_node(1,Node_pt[node_count]);
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(
437 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
438 finite_element_pt(ielem_neigh)->
439 node_pt(jnod_local_neigh)->x(i));
440 if (error>node_kill_tol)
442 oomph_info <<
"Error in node killing for i " 443 << i <<
" " << error << std::endl;
449 delete finite_element_pt(ielem)->node_pt(jnod_local);
453 finite_element_pt(ielem)->node_pt(jnod_local)=
454 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
479 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
480 finite_element_pt(ielem_neigh)->
481 node_pt(jnod_local_neigh)->x(i));
482 if (error>node_kill_tol)
484 oomph_info <<
"Error in node killing for i " 485 << i <<
" " << error << std::endl;
491 delete finite_element_pt(ielem)->node_pt(jnod_local);
495 finite_element_pt(ielem)->node_pt(jnod_local)=
496 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
519 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
520 finite_element_pt(ielem_neigh)->
521 node_pt(jnod_local_neigh)->x(i));
522 if (error>node_kill_tol)
524 oomph_info <<
"Error in node killing for i " 525 << i <<
" " << error << std::endl;
531 delete finite_element_pt(ielem)->node_pt(jnod_local);
535 finite_element_pt(ielem)->node_pt(jnod_local)=
536 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
543 Node_pt[node_count]=finite_element_pt(ielem)->
549 if ((i2==0)&&(ilayer==0))
551 this->convert_to_boundary_node(Node_pt[node_count]);
552 add_boundary_node(0,Node_pt[node_count]);
556 if ((i2==n_p-1)&&(ilayer==nlayer-1))
558 this->convert_to_boundary_node(Node_pt[node_count]);
559 add_boundary_node(2,Node_pt[node_count]);
565 this->convert_to_boundary_node(Node_pt[node_count]);
566 add_boundary_node(1,Node_pt[node_count]);
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(
634 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
635 finite_element_pt(ielem_neigh)->
636 node_pt(jnod_local_neigh)->x(i));
637 if (error>node_kill_tol)
639 oomph_info <<
"Error in node killing for i " 640 << i <<
" " << error << std::endl;
646 delete finite_element_pt(ielem)->node_pt(jnod_local);
650 finite_element_pt(ielem)->node_pt(jnod_local)=
651 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
676 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
677 finite_element_pt(ielem_neigh)->
678 node_pt(jnod_local_neigh)->x(i));
679 if (error>node_kill_tol)
681 oomph_info <<
"Error in node killing for i " 682 << i <<
" " << error << std::endl;
688 delete finite_element_pt(ielem)->node_pt(jnod_local);
692 finite_element_pt(ielem)->node_pt(jnod_local)=
693 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
715 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
716 finite_element_pt(ielem_neigh)->
717 node_pt(jnod_local_neigh)->x(i));
718 if (error>node_kill_tol)
720 oomph_info <<
"Error in node killing for i " 721 << i <<
" " << error << std::endl;
727 delete finite_element_pt(ielem)->node_pt(jnod_local);
731 finite_element_pt(ielem)->node_pt(jnod_local)=
732 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
739 Node_pt[node_count]=finite_element_pt(ielem)->
745 if ((i2==0)&&(ilayer==0))
747 this->convert_to_boundary_node(Node_pt[node_count]);
748 add_boundary_node(0,Node_pt[node_count]);
752 if ((i2==n_p-1)&&(ilayer==nlayer-1))
754 this->convert_to_boundary_node(Node_pt[node_count]);
755 add_boundary_node(2,Node_pt[node_count]);
761 this->convert_to_boundary_node(Node_pt[node_count]);
762 add_boundary_node(1,Node_pt[node_count]);
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(
830 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
831 finite_element_pt(ielem_neigh)->
832 node_pt(jnod_local_neigh)->x(i));
833 if (error>node_kill_tol)
835 oomph_info <<
"Error in node killing for i " 836 << i <<
" " << error << std::endl;
842 delete finite_element_pt(ielem)->node_pt(jnod_local);
846 finite_element_pt(ielem)->node_pt(jnod_local)=
847 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
872 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
873 finite_element_pt(ielem_neigh)->
874 node_pt(jnod_local_neigh)->x(i));
875 if (error>node_kill_tol)
877 oomph_info <<
"Error in node killing for i " 878 << i <<
" " << error << std::endl;
884 delete finite_element_pt(ielem)->node_pt(jnod_local);
888 finite_element_pt(ielem)->node_pt(jnod_local)=
889 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
911 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
912 finite_element_pt(ielem_neigh)->
913 node_pt(jnod_local_neigh)->x(i));
914 if (error>node_kill_tol)
916 oomph_info <<
"Error in node killing for i " 917 << i <<
" " << error << std::endl;
923 delete finite_element_pt(ielem)->node_pt(jnod_local);
927 finite_element_pt(ielem)->node_pt(jnod_local)=
928 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
950 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
951 finite_element_pt(ielem_neigh)->
952 node_pt(jnod_local_neigh)->x(i));
953 if (error>node_kill_tol)
955 oomph_info <<
"Error in node killing for i " 956 << i <<
" " << error << std::endl;
962 delete finite_element_pt(ielem)->node_pt(jnod_local);
966 finite_element_pt(ielem)->node_pt(jnod_local)=
967 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
975 Node_pt[node_count]=finite_element_pt(ielem)->
981 if ((i2==0)&&(ilayer==0))
983 this->convert_to_boundary_node(Node_pt[node_count]);
984 add_boundary_node(0,Node_pt[node_count]);
988 if ((i2==n_p-1)&&(ilayer==nlayer-1))
990 this->convert_to_boundary_node(Node_pt[node_count]);
991 add_boundary_node(2,Node_pt[node_count]);
997 this->convert_to_boundary_node(Node_pt[node_count]);
998 add_boundary_node(1,Node_pt[node_count]);
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";
1036 throw OomphLibError(error_stream.str(),
1037 OOMPH_CURRENT_FUNCTION,
1038 OOMPH_EXCEPTION_LOCATION);
1042 setup_boundary_element_info();
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...
Tube as a domain. The entire domain must be defined by a GeomObject with the following convention: ze...
TubeDomain * Domain_pt
Pointer to domain.