31 #ifndef OOMPH_TETMESH_HEADER 32 #define OOMPH_TETMESH_HEADER 36 #include <oomph-lib-config.h> 68 std::ostringstream error_stream;
70 <<
"TetMeshVertex should only be used in 3D!\n" 71 <<
"Your Vector of coordinates, contains data for " 73 <<
"-dimensional coordinates." << std::endl;
75 OOMPH_CURRENT_FUNCTION,
76 OOMPH_EXCEPTION_LOCATION);
88 std::ostringstream error_stream;
90 <<
"TetMeshVertex should only be used in 3D!\n" 91 <<
"Your Vector of intrinisic coordinates, contains data for " 93 <<
"-dimensional coordinates but should be 2!" << std::endl;
95 OOMPH_CURRENT_FUNCTION,
96 OOMPH_EXCEPTION_LOCATION);
111 double x(
const unsigned&
i)
const 164 One_based_region_id_that_facet_is_embedded_in(0)
167 Vertex_pt.resize(nvertex,0);
173 return Vertex_pt.size();
186 Vertex_pt[j]=vertex_pt;
207 unsigned nv=Vertex_pt.size();
208 for (
unsigned j=0;j<nv;j++)
223 One_based_adjacent_region_id.insert(one_based_id);
229 return One_based_adjacent_region_id;
235 return (One_based_region_id_that_facet_is_embedded_in!=0);
242 One_based_region_id_that_facet_is_embedded_in=one_based_region_id;
249 return One_based_region_id_that_facet_is_embedded_in;
255 unsigned n=Vertex_pt.size();
256 outfile <<
"ZONE I=" << n+1 << std::endl;
257 for (
unsigned j=0;j<n;j++)
259 outfile << Vertex_pt[j]->x(0) <<
" " 260 << Vertex_pt[j]->x(1) <<
" " 261 << Vertex_pt[j]->x(2) <<
" " 265 outfile << Vertex_pt[0]->x(0) <<
" " 266 << Vertex_pt[0]->x(1) <<
" " 267 << Vertex_pt[0]->x(2) <<
" " 308 Geom_object_with_boundaries_pt(0)
317 return Vertex_pt.size();
323 return Facet_pt.size();
329 return Facet_pt[j]->one_based_boundary_id();
335 return Vertex_pt[j]->one_based_boundary_id();
341 return Vertex_pt[j]->x(i);
347 return Facet_pt[j]->nvertex();
353 return Boundaries_can_be_split_in_tetgen;
359 Boundaries_can_be_split_in_tetgen=
true;
365 Boundaries_can_be_split_in_tetgen=
false;
384 return Geom_object_with_boundaries_pt;
390 unsigned n=Facet_pt.size();
391 for (
unsigned j=0;j<n;j++)
393 Facet_pt[j]->output(outfile);
401 std::ofstream outfile;
402 outfile.open(filename.c_str());
414 const double& zeta_boundary,
418 zeta_vertex[0]=Facet_pt[facet_id]->vertex_pt(0)->zeta_in_geom_object();
419 zeta_vertex[1]=Facet_pt[facet_id]->vertex_pt(1)->zeta_in_geom_object();
420 zeta[0]=zeta_vertex[0][0]+(zeta_vertex[1][0]-zeta_vertex[0][0])*zeta_boundary;
421 zeta[1]=zeta_vertex[0][1]+(zeta_vertex[1][1]-zeta_vertex[0][1])*zeta_boundary;
431 const double& zeta_boundary,
435 zeta_vertex[0]=Facet_pt[facet_id]->vertex_pt(1)->zeta_in_geom_object();
436 zeta_vertex[1]=Facet_pt[facet_id]->vertex_pt(2)->zeta_in_geom_object();
437 zeta[0]=zeta_vertex[0][0]+(zeta_vertex[1][0]-zeta_vertex[0][0])*zeta_boundary;
438 zeta[1]=zeta_vertex[0][1]+(zeta_vertex[1][1]-zeta_vertex[0][1])*zeta_boundary;
448 const double& zeta_boundary,
452 zeta_vertex[0]=Facet_pt[facet_id]->vertex_pt(2)->zeta_in_geom_object();
453 zeta_vertex[1]=Facet_pt[facet_id]->vertex_pt(0)->zeta_in_geom_object();
454 zeta[0]=zeta_vertex[0][0]+(zeta_vertex[1][0]-zeta_vertex[0][0])*zeta_boundary;
455 zeta[1]=zeta_vertex[0][1]+(zeta_vertex[1][1]-zeta_vertex[0][1])*zeta_boundary;
464 if (Facet_vertex_index_in_tetgen.size()!=nfacet())
466 setup_facet_connectivity_for_tetgen();
468 return Facet_vertex_index_in_tetgen[f];
497 unsigned nv_overall=Vertex_pt.size();
498 unsigned nf=nfacet();
499 Facet_vertex_index_in_tetgen.resize(nf);
500 for (
unsigned f=0;f<nf;f++)
502 unsigned nv=Facet_pt[f]->nvertex();
503 Facet_vertex_index_in_tetgen[f].resize(nv);
504 for (
unsigned v=0;v<nv;v++)
507 for (
unsigned j=0;j<nv_overall;j++)
509 if (my_vertex_pt==Vertex_pt[j])
511 Facet_vertex_index_in_tetgen[f][v]=j;
540 Faceted_volume_represents_hole_for_gmsh(false)
549 Faceted_volume_represents_hole_for_gmsh=
true;
555 Faceted_volume_represents_hole_for_gmsh=
false;
561 return Faceted_volume_represents_hole_for_gmsh;
566 const unsigned &
i)
const 568 return (Internal_point_for_tetgen[j].first)[
i];
574 Internal_point_for_tetgen.push_back(std::make_pair(hole_point,-1));
582 Internal_point_for_tetgen.push_back(std::make_pair(region_point,region_id));
589 return Internal_point_for_tetgen.size();
596 return Internal_point_for_tetgen[j].second;
603 return (Internal_point_for_tetgen[j].second<0);
609 return (Internal_point_for_tetgen[j].second>=0);
674 void assess_mesh_quality(std::ofstream& some_file);
693 template<
class ELEMENT>
697 std::ofstream some_file;
700 bool switch_normal=
false;
701 this->setup_boundary_coordinates<ELEMENT>
702 (b,switch_normal,some_file);
724 template<
class ELEMENT>
728 std::ofstream some_file;
730 this->setup_boundary_coordinates<ELEMENT>
731 (b,switch_normal,some_file);
754 template<
class ELEMENT>
755 void setup_boundary_coordinates(
const unsigned& b,
756 const bool& switch_normal,
757 std::ofstream& outfile);
777 template<
class ELEMENT>
779 std::ofstream& outfile)
782 bool switch_normal=
false;
783 this->setup_boundary_coordinates<ELEMENT>
784 (b,switch_normal,outfile);
790 const unsigned &r)
const 794 std::map<unsigned,Vector<FiniteElement*> >::const_iterator it =
795 Boundary_region_element_pt[b].find(r);
796 if(it!=Boundary_region_element_pt[b].end())
798 return (it->second).size();
810 const unsigned &
e)
const 813 std::map<unsigned,Vector<FiniteElement*> >::const_iterator it =
814 Boundary_region_element_pt[b].find(r);
815 if(it!=Boundary_region_element_pt[b].end())
817 return (it->second)[
e];
828 const unsigned &
e)
const 831 std::map<unsigned,Vector<int> >::const_iterator it =
832 Face_index_region_at_boundary[b].find(r);
833 if(it!=Face_index_region_at_boundary[b].end())
835 return (it->second)[
e];
839 std::ostringstream error_message;
840 error_message <<
"Face indices not set up for boundary " 841 << b <<
" in region " << r <<
"\n";
843 <<
"This probably means that the boundary is not adjacent to region\n";
845 OOMPH_CURRENT_FUNCTION,
846 OOMPH_EXCEPTION_LOCATION);
854 return Region_element_pt.size();
862 unsigned n=Region_attribute.size();
863 for (
unsigned i=0;
i<n;
i++)
868 static_cast<double>(static_cast<unsigned>(Region_attribute[
i])));
871 std::ostringstream error_message;
873 <<
"Region attributes should be unsigneds because we \n" 874 <<
"only use them to set region ids\n";
876 OOMPH_CURRENT_FUNCTION,
877 OOMPH_EXCEPTION_LOCATION);
880 if (static_cast<unsigned>(Region_attribute[i])==r)
889 return Region_element_pt[entry].size();
901 return Region_attribute[
i];
910 unsigned n=Region_attribute.
size();
911 for (
unsigned i=0;
i<n;
i++)
916 static_cast<double>(static_cast<unsigned>(Region_attribute[
i])));
919 std::ostringstream error_message;
921 <<
"Region attributes should be unsigneds because we \n" 922 <<
"only use the to set region ids\n";
924 OOMPH_CURRENT_FUNCTION,
925 OOMPH_EXCEPTION_LOCATION);
928 if (static_cast<unsigned>(Region_attribute[i])==r)
937 return Region_element_pt[entry][
e];
956 template<
class ELEMENT>
959 const bool& switch_normal,
972 template<
class ELEMENT>
975 const bool& switch_normal)
980 snap_to_quadratic_surface<ELEMENT>
981 (boundary_id,quadratic_surface_file_name,
982 switch_normal,doc_info);
989 void snap_nodes_onto_geometric_objects();
995 template<
class ELEMENT>
996 void split_elements_in_corners(
TimeStepper* time_stepper_pt=
1006 std::ofstream outfile;
1007 this->setup_boundary_element_info(outfile);
1013 void setup_boundary_element_info(std::ostream &outfile);
1051 std::map<unsigned,Vector<Vector<double> > >
1093 template <
class ELEMENT>
1096 const bool& switch_normal,
1097 std::ofstream& outfile)
1099 Node* lower_left_node_pt=0;
1100 Node* upper_right_node_pt=0;
1111 std::map<unsigned,TetMeshFacet*>::iterator it=
1112 Tet_mesh_facet_pt.find(b);
1113 if (it!=Tet_mesh_facet_pt.end())
1126 bool vertices_are_in_same_plane=
true;
1127 for (
unsigned do_for_real=0;do_for_real<2;do_for_real++)
1134 unsigned nel=this->nboundary_element(b);
1139 for(
unsigned e=0;
e<nel;
e++)
1145 int face_index = this->face_index_at_boundary(b,
e);
1149 bulk_elem_pt,face_index));
1152 if (outfile.is_open())
1154 face_el_pt[face_el_pt.size()-1]->output(outfile);
1159 lower_left_node_pt=this->boundary_node_pt(b,0);
1160 upper_right_node_pt=this->boundary_node_pt(b,0);
1163 unsigned nnod=this->nboundary_node(b);
1164 for (
unsigned j=0;j<nnod;j++)
1168 Node* nod_pt=this->boundary_node_pt(b,j);
1171 if (nod_pt->
x(2)<lower_left_node_pt->
x(2))
1173 lower_left_node_pt=nod_pt;
1176 else if (nod_pt->
x(2)==lower_left_node_pt->
x(2))
1179 if (nod_pt->
x(1)<lower_left_node_pt->
x(1))
1181 lower_left_node_pt=nod_pt;
1184 else if (nod_pt->
x(1)==lower_left_node_pt->
x(1))
1188 if (nod_pt->
x(0)<lower_left_node_pt->
x(0))
1190 lower_left_node_pt=nod_pt;
1196 if (nod_pt->
x(2)>upper_right_node_pt->
x(2))
1198 upper_right_node_pt=nod_pt;
1201 else if (nod_pt->
x(2)==upper_right_node_pt->
x(2))
1204 if (nod_pt->
x(1)>upper_right_node_pt->
x(1))
1206 upper_right_node_pt=nod_pt;
1209 else if (nod_pt->
x(1)==upper_right_node_pt->
x(1))
1213 if (nod_pt->
x(0)>upper_right_node_pt->
x(0))
1215 upper_right_node_pt=nod_pt;
1225 b0[0]=upper_right_node_pt->
x(0)-lower_left_node_pt->
x(0);
1226 b0[1]=upper_right_node_pt->
x(1)-lower_left_node_pt->
x(1);
1227 b0[2]=upper_right_node_pt->
x(2)-lower_left_node_pt->
x(2);
1230 double inv_length=1.0/sqrt(b0[0]*b0[0]+b0[1]*b0[1]+b0[2]*b0[2]);
1241 outer_unit_normal(s,normal);
1269 normal[0]=t1y*t2z-t1z*t2y;
1270 normal[1]=t1z*t2x-t1x*t2z;
1271 normal[2]=t1x*t2y-t1y*t2x;
1272 double inv_length=1.0/sqrt(normal[0]*normal[0]+
1273 normal[1]*normal[1]+
1274 normal[2]*normal[2]);
1275 normal[0]*=inv_length;
1276 normal[1]*=inv_length;
1277 normal[2]*=inv_length;
1282 normal[0]=-normal[0];
1283 normal[1]=-normal[1];
1284 normal[2]=-normal[2];
1288 for(
unsigned e=0;
e<nel;
e++)
1293 outer_unit_normal(s,my_normal);
1297 normal[0]*my_normal[0]+
1298 normal[1]*my_normal[1]+
1299 normal[2]*my_normal[2];
1302 double error=abs(dot_prod)-1.0;
1303 if (abs(error)>Tolerance_for_boundary_finding)
1305 vertices_are_in_same_plane=
false;
1310 if (vertices_are_in_same_plane)
1314 b1[0]=b0[1]*normal[2]-b0[2]*normal[1];
1315 b1[1]=b0[2]*normal[0]-b0[0]*normal[2];
1316 b1[2]=b0[0]*normal[1]-b0[1]*normal[0];
1321 for (
unsigned j=0;j<nnod;j++)
1324 Node* nod_pt=this->boundary_node_pt(b,j);
1328 delta[0]=nod_pt->
x(0)-lower_left_node_pt->
x(0);
1329 delta[1]=nod_pt->
x(1)-lower_left_node_pt->
x(1);
1330 delta[2]=nod_pt->
x(2)-lower_left_node_pt->
x(2);
1333 zeta[0]=delta[0]*b0[0]+delta[1]*b0[1]+delta[2]*b0[2];
1334 zeta[1]=delta[0]*b1[0]+delta[1]*b1[1]+delta[2]*b1[2];
1338 pow(lower_left_node_pt->
x(0)+zeta[0]*b0[0]+zeta[1]*b1[0]-nod_pt->
x(0),2)+
1339 pow(lower_left_node_pt->
x(1)+zeta[0]*b0[1]+zeta[1]*b1[1]-nod_pt->
x(1),2)+
1340 pow(lower_left_node_pt->
x(2)+zeta[0]*b0[2]+zeta[1]*b1[2]-nod_pt->
x(2),2);
1342 if (sqrt(error)>Tolerance_for_boundary_finding)
1344 std::ostringstream error_message;
1346 <<
"Error in projection of boundary coordinates = " 1347 << sqrt(error) <<
" > Tolerance_for_boundary_finding = " 1348 << Tolerance_for_boundary_finding << std::endl
1349 <<
"nv = " << nv << std::endl
1351 << lower_left_node_pt->
x(0) <<
" " 1352 << lower_left_node_pt->
x(1) <<
" " 1353 << lower_left_node_pt->
x(2) <<
" " 1356 << upper_right_node_pt->
x(0) <<
" " 1357 << upper_right_node_pt->
x(1) <<
" " 1358 << upper_right_node_pt->
x(2) <<
" " 1361 for (
unsigned j=0;j<nnod;j++)
1364 Node* nod_pt=this->boundary_node_pt(b,j);
1365 error_message << nod_pt->
x(0) <<
" " 1366 << nod_pt->
x(1) <<
" " 1367 << nod_pt->
x(2) <<
" " 1371 OOMPH_CURRENT_FUNCTION,
1372 OOMPH_EXCEPTION_LOCATION);
1388 Boundary_coordinate_exists[b]=
true;
1396 Triangular_facet_vertex_boundary_coordinate[b].resize(3);
1397 for (
unsigned j=0;j<3;j++)
1400 Triangular_facet_vertex_boundary_coordinate[b][j].resize(2);
1406 lower_left_node_pt->
x(0);
1409 lower_left_node_pt->
x(1);
1412 lower_left_node_pt->
x(2);
1416 zeta[0]=delta[0]*b0[0]+delta[1]*b0[1]+delta[2]*b0[2];
1417 zeta[1]=delta[0]*b1[0]+delta[1]*b1[1]+delta[2]*b1[2];
1419 for (
unsigned ii=0;ii<2;ii++)
1421 Triangular_facet_vertex_boundary_coordinate[b][j][ii]=
1430 unsigned n=face_el_pt.size();
1431 for (
unsigned e=0;
e<n;
e++)
1433 delete face_el_pt[
e];
1437 if (!vertices_are_in_same_plane)
1461 template<
class ELEMENT>
1465 const bool& switch_normal,
1473 std::ofstream the_file_non_snapped;
1474 std::string non_snapped_filename=
"non_snapped_nodes_"+doc_info.
label()+
".dat";
1477 std::ifstream infile(quadratic_surface_file_name.c_str(),std::ios_base::in);
1482 infile.getline(dummy, 100);
1489 infile.getline(dummy, 100);
1492 if (nel!=boundary_id.size())
1494 std::ostringstream error_message;
1496 <<
"Number of quadratic facets specified in " 1497 << quadratic_surface_file_name <<
"is: " << nel
1498 <<
"\nThis doesn't match the number of planar boundaries \n" 1499 <<
"specified in boundary_id which is " << boundary_id.size()
1502 OOMPH_CURRENT_FUNCTION,
1503 OOMPH_EXCEPTION_LOCATION);
1510 for(
unsigned e=0;
e<nel;
e++)
1518 unsigned n_position_type=1;
1519 unsigned initial_n_value=0;
1522 std::map<unsigned,unsigned> node_number;
1523 std::ofstream node_file;
1524 for (
unsigned j=0;j<n_node;j++)
1527 infile >> nod_pt[j]->x(0);
1528 infile >> nod_pt[j]->x(1);
1529 infile >> nod_pt[j]->x(2);
1530 infile >> node_nmbr;
1531 node_number[node_nmbr]=j;
1538 for(
unsigned e=0;
e<nel;
e++)
1540 unsigned nnod_el=face_el_pt[
e]->nnode();
1542 for (
unsigned j=0;j<nnod_el;j++)
1545 face_el_pt[
e]->node_pt(j)=nod_pt[node_number[j_global]];
1546 face_el_pt[
e]->node_pt(j)->add_to_boundary(boundary_id[
e]);
1548 face_el_pt[
e]->set_boundary_number_in_bulk_mesh(boundary_id[
e]);
1549 face_el_pt[
e]->set_nodal_dimension(3);
1558 for (
unsigned e=0;
e<nel;
e++)
1563 Node* lower_left_node_pt=face_el_pt[
e]->node_pt(0);
1564 Node* upper_right_node_pt=face_el_pt[
e]->node_pt(0);
1567 for (
unsigned j=0;j<3;j++)
1570 Node* nod_pt=face_el_pt[
e]->node_pt(j);
1573 if (nod_pt->
x(2)<lower_left_node_pt->
x(2))
1575 lower_left_node_pt=nod_pt;
1578 else if (nod_pt->
x(2)==lower_left_node_pt->
x(2))
1581 if (nod_pt->
x(1)<lower_left_node_pt->
x(1))
1583 lower_left_node_pt=nod_pt;
1586 else if (nod_pt->
x(1)==lower_left_node_pt->
x(1))
1590 if (nod_pt->
x(0)<lower_left_node_pt->
x(0))
1592 lower_left_node_pt=nod_pt;
1598 if (nod_pt->
x(2)>upper_right_node_pt->
x(2))
1600 upper_right_node_pt=nod_pt;
1603 else if (nod_pt->
x(2)==upper_right_node_pt->
x(2))
1606 if (nod_pt->
x(1)>upper_right_node_pt->
x(1))
1608 upper_right_node_pt=nod_pt;
1611 else if (nod_pt->
x(1)==upper_right_node_pt->
x(1))
1615 if (nod_pt->
x(0)>upper_right_node_pt->
x(0))
1617 upper_right_node_pt=nod_pt;
1628 b0[0]=upper_right_node_pt->
x(0)-lower_left_node_pt->
x(0);
1629 b0[1]=upper_right_node_pt->
x(1)-lower_left_node_pt->
x(1);
1630 b0[2]=upper_right_node_pt->
x(2)-lower_left_node_pt->
x(2);
1633 double inv_length=1.0/sqrt(b0[0]*b0[0]+b0[1]*b0[1]+b0[2]*b0[2]);
1645 tang1[0]=face_el_pt[
e]->node_pt(1)->x(0)-face_el_pt[
e]->node_pt(0)->x(0);
1646 tang1[1]=face_el_pt[
e]->node_pt(1)->x(1)-face_el_pt[
e]->node_pt(0)->x(1);
1647 tang1[2]=face_el_pt[
e]->node_pt(1)->x(2)-face_el_pt[
e]->node_pt(0)->x(2);
1648 tang2[0]=face_el_pt[
e]->node_pt(2)->x(0)-face_el_pt[
e]->node_pt(0)->x(0);
1649 tang2[1]=face_el_pt[
e]->node_pt(2)->x(1)-face_el_pt[
e]->node_pt(0)->x(1);
1650 tang2[2]=face_el_pt[
e]->node_pt(2)->x(2)-face_el_pt[
e]->node_pt(0)->x(2);
1651 normal[0]=-(tang1[1]*tang2[2]-tang1[2]*tang2[1]);
1652 normal[1]=-(tang1[2]*tang2[0]-tang1[0]*tang2[2]);
1653 normal[2]=-(tang1[0]*tang2[1]-tang1[1]*tang2[0]);
1657 1.0/sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
1658 normal[0]*=inv_length;
1659 normal[1]*=inv_length;
1660 normal[2]*=inv_length;
1665 normal[0]=-normal[0];
1666 normal[1]=-normal[1];
1667 normal[2]=-normal[2];
1672 b1[0]=b0[1]*normal[2]-b0[2]*normal[1];
1673 b1[1]=b0[2]*normal[0]-b0[0]*normal[2];
1674 b1[2]=b0[0]*normal[1]-b0[1]*normal[0];
1677 for (
unsigned j=0;j<3;j++)
1680 Node* nod_pt=face_el_pt[
e]->node_pt(j);
1684 delta[0]=nod_pt->
x(0)-lower_left_node_pt->
x(0);
1685 delta[1]=nod_pt->
x(1)-lower_left_node_pt->
x(1);
1686 delta[2]=nod_pt->
x(2)-lower_left_node_pt->
x(2);
1689 zeta[0]=delta[0]*b0[0]+delta[1]*b0[1]+delta[2]*b0[2];
1690 zeta[1]=delta[0]*b1[0]+delta[1]*b1[1]+delta[2]*b1[2];
1692 vertex_boundary_coord[j].resize(2);
1693 vertex_boundary_coord[j][0]=zeta[0];
1694 vertex_boundary_coord[j][1]=zeta[1];
1700 pow(lower_left_node_pt->
x(0)+zeta[0]*b0[0]+zeta[1]*b1[0]-nod_pt->
x(0),2)+
1701 pow(lower_left_node_pt->
x(1)+zeta[0]*b0[1]+zeta[1]*b1[1]-nod_pt->
x(1),2)+
1702 pow(lower_left_node_pt->
x(2)+zeta[0]*b0[2]+zeta[1]*b1[2]-nod_pt->
x(2),2);
1704 if (sqrt(error)>Tolerance_for_boundary_finding)
1706 std::ostringstream error_message;
1708 <<
"Error in setup of boundary coordinate " 1709 << sqrt(error) << std::endl
1710 <<
"exceeds tolerance specified by the static member data\n" 1711 <<
"TetMeshBase::Tolerance_for_boundary_finding = " 1712 << Tolerance_for_boundary_finding << std::endl
1713 <<
"This usually means that the boundary is not planar.\n\n" 1714 <<
"You can suppress this error message by recompiling \n" 1715 <<
"recompiling without PARANOID or by changing the tolerance.\n";
1717 OOMPH_CURRENT_FUNCTION,
1718 OOMPH_EXCEPTION_LOCATION);
1731 zeta[0]=0.5*(vertex_boundary_coord[0][0]+vertex_boundary_coord[1][0]);
1732 zeta[1]=0.5*(vertex_boundary_coord[0][1]+vertex_boundary_coord[1][1]);
1733 face_el_pt[
e]->node_pt(3)->set_coordinates_on_boundary(boundary_id[
e],zeta);
1736 zeta[0]=0.5*(vertex_boundary_coord[1][0]+vertex_boundary_coord[2][0]);
1737 zeta[1]=0.5*(vertex_boundary_coord[1][1]+vertex_boundary_coord[2][1]);
1738 face_el_pt[
e]->node_pt(4)->set_coordinates_on_boundary(boundary_id[e],zeta);
1741 zeta[0]=0.5*(vertex_boundary_coord[2][0]+vertex_boundary_coord[0][0]);
1742 zeta[1]=0.5*(vertex_boundary_coord[2][1]+vertex_boundary_coord[0][1]);
1743 face_el_pt[
e]->node_pt(5)->set_coordinates_on_boundary(boundary_id[e],zeta);
1750 for(
unsigned b=0;b<nel;b++)
1754 std::ofstream the_file;
1755 std::ofstream the_file_before;
1756 std::ofstream the_file_after;
1759 std::ostringstream filename;
1760 filename << doc_info.
directory() <<
"/quadratic_coordinates_" 1761 << doc_info.
label() << b <<
".dat";
1762 the_file.open(filename.str().c_str());
1764 std::ostringstream filename1;
1765 filename1 << doc_info.
directory() <<
"/quadratic_nodes_before_" 1766 << doc_info.
label() << b <<
".dat";
1767 the_file_before.open(filename1.str().c_str());
1769 std::ostringstream filename2;
1770 filename2 << doc_info.
directory() <<
"/quadratic_nodes_after_" 1771 << doc_info.
label() << b <<
".dat";
1772 the_file_after.open(filename2.str().c_str());
1785 the_file << el_pt->tecplot_zone_string(n_plot);
1788 unsigned num_plot_points=el_pt->nplot_points(n_plot);
1789 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
1792 el_pt->get_s_plot(iplot,n_plot,s);
1793 el_pt->interpolated_zeta(s,zeta);
1794 el_pt->interpolated_x(s,x);
1795 for (
unsigned i=0;
i<3;
i++)
1797 the_file << x[
i] <<
" ";
1799 for (
unsigned i=0;
i<2;
i++)
1801 the_file << zeta[
i] <<
" ";
1803 the_file << std::endl;
1805 el_pt->write_tecplot_zone_footer(the_file,n_plot);
1819 unsigned nel=this->nboundary_element(boundary_id[b]);
1820 for (
unsigned e=0;
e<nel;
e++)
1823 FiniteElement* bulk_elem_pt=this->boundary_element_pt(boundary_id[b],
e);
1826 unsigned nnod=bulk_elem_pt->
nnode();
1827 for (
unsigned j=0;j<nnod;j++)
1837 the_file_before << nod_pt->
x(0) <<
" " 1838 << nod_pt->
x(1) <<
" " 1839 << nod_pt->
x(2) <<
" " 1840 << boundary_zeta[0] <<
" " 1841 << boundary_zeta[1] <<
" " 1846 el_pt->locate_zeta(boundary_zeta,geom_obj_pt,s_geom_obj);
1849 geom_obj_pt->
position(s_geom_obj,quadratic_coordinates);
1850 nod_pt->
x(0)=quadratic_coordinates[0];
1851 nod_pt->
x(1)=quadratic_coordinates[1];
1852 nod_pt->
x(2)=quadratic_coordinates[2];
1859 std::ostringstream error_message;
1861 <<
"Warning: Couldn't find GeomObject during snapping to\n" 1862 <<
"quadratic surface for boundary " << boundary_id[b]
1863 <<
". I'm leaving the node where it was. Will bail out later.\n";
1865 error_message.str(),
1866 "TetgenMesh::snap_to_quadratic_surface()",
1867 OOMPH_EXCEPTION_LOCATION);
1868 if (!the_file_non_snapped.is_open())
1870 the_file_non_snapped.open(non_snapped_filename.c_str());
1872 the_file_non_snapped << nod_pt->
x(0) <<
" " 1873 << nod_pt->
x(1) <<
" " 1874 << nod_pt->
x(2) <<
" " 1875 << boundary_zeta[0] <<
" " 1876 << boundary_zeta[1] <<
" " 1883 the_file_after << nod_pt->
x(0) <<
" " 1884 << nod_pt->
x(1) <<
" " 1885 << nod_pt->
x(2) <<
" " 1886 << boundary_zeta[0] <<
" " 1887 << boundary_zeta[1] <<
" " 1896 the_file_before.close();
1897 the_file_after.close();
1903 std::ostringstream error_message;
1905 <<
"Warning: Couldn't find GeomObject during snapping to\n" 1906 <<
"quadratic surface. Bailing out.\n" 1907 <<
"Nodes that couldn't be snapped are contained in \n" 1908 <<
"file: " << non_snapped_filename <<
".\n" 1909 <<
"This problem may arise because the switch_normal flag was \n" 1910 <<
"set wrongly.\n";
1912 error_message.str(),
1913 OOMPH_CURRENT_FUNCTION,
1914 OOMPH_EXCEPTION_LOCATION);
1918 if (!the_file_non_snapped.is_open())
1920 the_file_non_snapped.close();
1924 for(
unsigned e=0;
e<nel;
e++)
1926 delete face_el_pt[
e];
1931 unsigned nn=nod_pt.size();
1932 for (
unsigned j=0;j<nn;j++)
1945 template <
class ELEMENT>
1950 if (!Lookup_for_elements_next_boundary_is_setup)
1952 setup_boundary_element_info();
1956 unsigned nnode_1d=finite_element_pt(0)->nnode_1d();
1958 unsigned nnode = this->finite_element_pt(0)->nnode();
1961 if ((nnode_1d!=2)&&(nnode_1d!=3))
1963 std::ostringstream error_message;
1964 error_message <<
"Mesh generation from tetgen currently only works\n";
1965 error_message <<
"for nnode_1d = 2 or 3. You're trying to use it\n";
1966 error_message <<
"for nnode_1d=" << nnode_1d << std::endl;
1969 OOMPH_CURRENT_FUNCTION,
1970 OOMPH_EXCEPTION_LOCATION);
1974 std::map<FiniteElement*,unsigned> count;
1977 unsigned nb=this->nboundary();
1978 for (
unsigned b=0;b<nb;b++)
1981 unsigned nel=this->nboundary_element(b);
1982 for (
unsigned e=0;
e<nel;
e++)
1995 std::set<FiniteElement*> elements_to_be_split;
1996 for (std::map<FiniteElement*,unsigned>::iterator it=count.begin();
1997 it!=count.end();it++)
2005 elements_to_be_split.insert(el_pt);
2010 unsigned nel=this->nelement();
2012 new_or_retained_el_pt.reserve(nel);
2015 std::map<FiniteElement*, Vector<FiniteElement*> > old_to_new_corner_element_map;
2018 for (
unsigned e=0;
e<nel;
e++)
2025 std::set<FiniteElement*>::iterator it=
2026 std::find(elements_to_be_split.begin(),elements_to_be_split.end(),el_pt);
2029 if (it==elements_to_be_split.end())
2032 new_or_retained_el_pt.push_back(el_pt);
2070 node0_pt = el_pt->
node_pt(14);
2071 el1_pt->
node_pt(2) = node0_pt;
2123 el2_pt->
node_pt(10) = node5_pt;
2155 el3_pt->
node_pt(10) = node6_pt;
2156 el3_pt->
node_pt(11) = node10_pt;
2188 el4_pt->
node_pt(10) = node9_pt;
2189 el4_pt->
node_pt(11) = node8_pt;
2191 el4_pt->
node_pt(13) = node7_pt;;
2196 new_or_retained_el_pt.push_back(el1_pt);
2197 new_or_retained_el_pt.push_back(el2_pt);
2198 new_or_retained_el_pt.push_back(el3_pt);
2199 new_or_retained_el_pt.push_back(el4_pt);
2203 temp_vec[0] = el1_pt;
2204 temp_vec[1] = el2_pt;
2205 temp_vec[2] = el3_pt;
2206 temp_vec[3] = el4_pt;
2209 old_to_new_corner_element_map.insert(
2214 this->add_node_pt(node0_pt);
2216 this->add_node_pt(node1_pt);
2217 this->add_node_pt(node2_pt);
2218 this->add_node_pt(node3_pt);
2219 this->add_node_pt(node4_pt);
2222 this->add_node_pt(node5_pt);
2223 this->add_node_pt(node6_pt);
2224 this->add_node_pt(node7_pt);
2225 this->add_node_pt(node8_pt);
2226 this->add_node_pt(node9_pt);
2230 for (
unsigned i=0;
i<3;
i++)
2243 node1_pt->
x(
i)=0.5*(el_pt->
node_pt(0)->
x(
i)+node0_pt->
x(
i));
2244 node2_pt->
x(
i)=0.5*(el_pt->
node_pt(1)->
x(
i)+node0_pt->
x(
i));
2245 node3_pt->
x(
i)=0.5*(el_pt->
node_pt(2)->
x(
i)+node0_pt->
x(
i));
2246 node4_pt->
x(
i)=0.5*(el_pt->
node_pt(3)->
x(
i)+node0_pt->
x(
i));
2257 for(
unsigned i=0;
i<3;++
i)
2265 for(
unsigned i=0;
i<3;++
i)
2273 for(
unsigned i=0;
i<3;++
i)
2281 for(
unsigned i=0;
i<3;++
i)
2289 for(
unsigned i=0;
i<3;++
i)
2297 for(
unsigned i=0;
i<3;++
i)
2308 for(
unsigned i=0;
i<3;++
i)
2310 double av_pos = 0.0;
2311 for(
unsigned j=0;j<4;j++)
2316 temp_nod_pt->
x(
i) = 0.25*av_pos;
2319 this->add_node_pt(temp_nod_pt);
2323 for(
unsigned i=0;
i<3;++
i)
2325 double av_pos = 0.0;
2326 for(
unsigned j=0;j<4;j++)
2330 temp_nod_pt->
x(
i) = 0.25*av_pos;
2332 this->add_node_pt(temp_nod_pt);
2336 for(
unsigned i=0;
i<3;++
i)
2338 double av_pos = 0.0;
2339 for(
unsigned j=0;j<4;j++)
2343 temp_nod_pt->
x(
i) = 0.25*av_pos;
2345 this->add_node_pt(temp_nod_pt);
2349 for(
unsigned i=0;
i<3;++
i)
2351 double av_pos = 0.0;
2352 for(
unsigned j=0;j<4;j++)
2356 temp_nod_pt->
x(
i) = 0.25*av_pos;
2358 this->add_node_pt(temp_nod_pt);
2371 nel=new_or_retained_el_pt.size();
2372 Element_pt.resize(nel);
2373 for (
unsigned e=0;
e<nel;
e++)
2375 Element_pt[
e]=new_or_retained_el_pt[
e];
2379 setup_boundary_element_info();
2397 if(Region_attribute.size() == 0)
2403 if(old_to_new_corner_element_map.size() == 0)
2405 oomph_info <<
"\nNo corner elements need splitting\n\n";
2414 old_to_new_corner_element_map.begin();
2415 map_it != old_to_new_corner_element_map.end(); map_it++)
2421 unsigned original_region_index = 0;
2434 for(
unsigned region_index=0;
2435 region_index<Region_element_pt.size(); region_index++)
2439 region_element_it = std::find(Region_element_pt[region_index].begin(),
2440 Region_element_pt[region_index].end(),
2444 if(region_element_it != Region_element_pt[region_index].end())
2447 original_region_index = region_index;
2462 std::ostringstream error_message;
2464 <<
"The corner element being split does not appear to be in any " 2465 <<
"region, so something has gone wrong with the region lookup scheme\n";
2468 OOMPH_CURRENT_FUNCTION,
2469 OOMPH_EXCEPTION_LOCATION);
2475 Region_element_pt[original_region_index].erase(region_element_it);
2476 for(
unsigned i=0;
i<4;
i++)
2478 Region_element_pt[original_region_index].push_back(new_el_pt[
i]);
2484 Face_index_region_at_boundary.clear();
2485 Boundary_region_element_pt.clear();
2487 Face_index_region_at_boundary.resize(nboundary());
2488 Boundary_region_element_pt.resize(nboundary());
2490 for(
unsigned b=0; b<nboundary(); b++)
2493 unsigned nel = this->nboundary_element(b);
2494 for (
unsigned e=0;
e<nel;
e++)
2499 for(
unsigned r_index=0; r_index<Region_attribute.size(); r_index++)
2501 unsigned region_id =
static_cast<unsigned>(
2502 Region_attribute[r_index]);
2505 std::find(Region_element_pt[r_index].begin(),
2506 Region_element_pt[r_index].end(), el_pt);
2510 if(it != Region_element_pt[r_index].end())
2512 Boundary_region_element_pt[b][region_id].push_back(el_pt);
2514 unsigned face_index = face_index_at_boundary(b,
e);
2515 Face_index_region_at_boundary[b][region_id].push_back(face_index);
2521 oomph_info <<
"\nNumber of outer corner elements split: " 2522 << old_to_new_corner_element_map.size() <<
"\n\n";
unsigned one_based_boundary_id() const
First (of possibly multiple) one-based boundary id.
bool boundaries_can_be_split_in_tetgen()
Test whether boundary can be split in tetgen.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
virtual void set_coordinates_on_boundary(const unsigned &b, const unsigned &k, const Vector< double > &boundary_zeta)
Set the vector of the k-th generalised boundary coordinates on mesh boundary b. Broken virtual interf...
static double Tolerance_for_boundary_finding
Global static data that specifies the permitted error in the setup of the boundary coordinates...
TetMeshVertex(const Vector< double > &x)
Constructor: Pass coordinates (length 3!)
bool faceted_volume_represents_hole_for_gmsh() const
Does closed surface represent hole for gmsh?
void set_hole_for_tetgen(const Vector< double > &hole_point)
Specify coordinate of hole for tetgen.
bool is_doc_enabled() const
Are we documenting?
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors. ...
void enable_boundaries_can_be_split_in_tetgen()
Test whether boundaries can be split in tetgen.
std::map< unsigned, Vector< Vector< double > > > Triangular_facet_vertex_boundary_coordinate
Boundary coordinates of vertices in triangular facets associated with given boundary. Is only set up for triangular facets!
void set_vertex_pt(const unsigned &j, TetMeshVertex *vertex_pt)
unsigned nvertex() const
Number of vertices.
Information for documentation of results: Directory and file number to enable output in the form RESL...
unsigned nregion()
Return the number of regions specified by attributes.
unsigned nvertex() const
Number of vertices.
TimeStepper * Time_stepper_pt
Timestepper used to build nodes.
std::string directory() const
Output directory.
TetMeshVertex * vertex_pt(const unsigned &j) const
Pointer to j-th vertex.
bool Boundaries_can_be_split_in_tetgen
Boolean to indicate whether extra vertices can be added on the boundary in tetgen.
Vector< double > X
Coordinate vector.
FiniteElement * boundary_element_in_region_pt(const unsigned &b, const unsigned &r, const unsigned &e) const
Return pointer to the e-th element adjacent to boundary b in region r.
DiskLikeGeomObjectWithBoundaries * Geom_object_with_boundaries_pt
GeomObject with boundaries associated with this surface.
std::string & label()
String used (e.g.) for labeling output files.
Vector< std::pair< Vector< double >, int > > Internal_point_for_tetgen
A general Finite Element class.
Base class for tet meshes (meshes made of 3D tet elements).
std::set< unsigned > One_based_adjacent_region_id
Set of one-based adjacent region ids; no adjacent region if it's zero.
void set_one_based_adjacent_region_id(const unsigned &one_based_id)
Set (one-based!) region ID this facet is adjacent to. Specification of zero argument is harmless as i...
bool facet_is_embedded_in_a_specified_region()
Boolean indicating that facet is embedded in a specified region.
bool Faceted_volume_represents_hole_for_gmsh
Does closed surface represent hole for gmsh?
virtual Node * construct_boundary_node(const unsigned &n)
Construct the local node n as a boundary node; that is a node that MAY be placed on a mesh boundary a...
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double x(const unsigned &i) const
i-th coordinate
TetMeshFacet * facet_pt(const unsigned &j) const
Pointer to j-th facet.
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
virtual void boundary_zeta12(const unsigned &facet_id, const double &zeta_boundary, Vector< double > &zeta)
Virtual function that specifies the variation of the zeta coordinates in the GeomObject along the bou...
void set_one_based_region_that_facet_is_embedded_in(const unsigned &one_based_region_id)
Facet is to be embedded in specified one-based region.
Vector< Vector< FiniteElement * > > Region_element_pt
Vectors of vectors of elements in each region (note: this just stores them; the region IDs are contai...
void set_region_for_tetgen(const unsigned ®ion_id, const Vector< double > ®ion_point)
Specify a region; pass (zero-based) region ID and coordinate of point in region for tetgen...
virtual void get_coordinates_on_boundary(const unsigned &b, const unsigned &k, Vector< double > &boundary_zeta)
Return the vector of the k-th generalised boundary coordinates on mesh boundary b. Broken virtual interface provides run-time error checking.
Vector< TetMeshVertex * > Vertex_pt
Pointer to vertices.
void output(std::ostream &outfile) const
Output.
TetMeshFacet(const unsigned &nvertex)
Constructor: Specify number of vertices.
int face_index_at_boundary_in_region(const unsigned &b, const unsigned &r, const unsigned &e) const
Return face index of the e-th element adjacent to boundary b in region r.
void split_elements_in_corners(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Non-Delaunay split elements that have three faces on a boundary into sons. Timestepper species timest...
Vector< TetMeshFacet * > Facet_pt
Vector of pointers to facets.
bool internal_point_identifies_region_for_tetgen(const unsigned &j)
Is j-th internal point for tetgen associated with a region?
unsigned One_based_boundary_id
(One-based!) boundary IDs this facet lives on
double & x(const unsigned &i)
Return the i-th nodal coordinate.
void setup_boundary_element_info()
virtual ~TetMeshFacetedSurface()
Empty destructor.
Vector< Vector< unsigned > > Facet_vertex_index_in_tetgen
Facet connectivity: Facet_vertex_index[f][j] is the index of the j-th vertex (in the Vertex_pt vector...
void set_one_based_boundary_id(const unsigned &one_based_id)
Set (one-based!) boundary IDs this facet lives on. Passed to any existing vertices and to any future ...
unsigned one_based_region_that_facet_is_embedded_in()
void setup_boundary_coordinates(const unsigned &b, const bool &switch_normal)
Setup boundary coordinate on boundary b which is assumed to be planar. Boundary coordinates are the x...
Vector< std::map< unsigned, Vector< FiniteElement * > > > Boundary_region_element_pt
Storage for elements adjacent to a boundary in a particular region.
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object. ...
unsigned one_based_vertex_boundary_id(const unsigned &j) const
First (of possibly multiple) one-based boundary id of j-th vertex.
A template Class for BoundaryNodes; that is Nodes that MAY live on the boundary of a Mesh...
TetMeshFacetedClosedSurface * Outer_boundary_pt
Faceted surface that defines outer boundaries.
std::map< unsigned, TetMeshFacetedSurface * > Tet_mesh_faceted_surface_pt
Reverse lookup scheme: Pointer to faceted surface (if any!) associated with boundary b...
Vector< std::map< unsigned, Vector< int > > > Face_index_region_at_boundary
Storage for the face index adjacent to a boundary in a particular region.
Vector< TetMeshVertex * > Vertex_pt
Vector pointers to vertices.
bool internal_point_identifies_hole_for_tetgen(const unsigned &j)
Is j-th internal point for tetgen associated with a hole?
void snap_to_quadratic_surface(const Vector< unsigned > &boundary_id, const std::string &quadratic_surface_file_name, const bool &switch_normal, DocInfo &doc_info)
Snap boundaries specified by the IDs listed in boundary_id to a quadratric surface, specified in the file quadratic_surface_file_name. This is usually used with vmtk-based meshes for which oomph-lib's xda to poly conversion code produces the files "quadratic_fsi_boundary.dat" and "quadratic_outer_solid_boundary.dat" which specify the quadratic FSI boundary (for the fluid and the solid) and the quadratic representation of the outer boundary of the solid. When used with these files, the flag switch_normal should be set to true when calling the function for the outer boundary of the solid. The DocInfo object can be used to label optional output files. (Uses directory and label).
virtual void boundary_zeta20(const unsigned &facet_id, const double &zeta_boundary, Vector< double > &zeta)
Virtual function that specifies the variation of the zeta coordinates in the GeomObject along the bou...
void setup_boundary_coordinates(const unsigned &b)
Setup boundary coordinate on boundary b which is assumed to be planar. Boundary coordinates are the x...
std::set< unsigned > one_based_adjacent_region_id() const
Return set of (one-based!) region IDs this facet is adjacent to.
DiskLikeGeomObjectWithBoundaries * geom_object_with_boundaries_pt()
Access to GeomObject with boundaries associated with this surface (Null if there isn't one!) ...
void set_zeta_in_geom_object(const Vector< double > &zeta)
Set intrinisic coordinates in GeomObject.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
unsigned nfacet() const
Number of facets.
void output(std::ostream &outfile)
Output with default number of plot points.
void output(std::ostream &outfile) const
Output.
virtual ~TetMeshBase()
Destructor (empty)
TetMeshFacetedClosedSurface()
Constructor:
Vector< double > Zeta_in_geom_object
Intrinisic coordinates in GeomObject (zero sized if there isn't one.
void disable_doc()
Disable documentation.
const int & region_id_for_tetgen(const unsigned &j) const
Return the (zero-based) region ID of j-th internal point for tetgen. Negative if it's actually a hole...
virtual void boundary_zeta01(const unsigned &facet_id, const double &zeta_boundary, Vector< double > &zeta)
Virtual function that specifies the variation of the zeta coordinates in the GeomObject along the bou...
Vector< unsigned > vertex_index_in_tetgen(const unsigned &f)
Facet connectivity: vertex_index[j] is the index of the j-th vertex (in the Vertex_pt vector) in face...
void enable_faceted_volume_represents_hole_for_gmsh()
Declare closed surface to represent hole for gmsh.
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
void operator=(const TetMeshBase &)
Broken assignment operator.
void output(const std::string &filename) const
Output.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
unsigned one_based_facet_boundary_id(const unsigned &j) const
One-based boundary id of j-th facet.
double region_attribute(const unsigned &i)
Return the i-th region attribute (here only used as the (assumed to be unsigned) region id...
void setup_facet_connectivity_for_tetgen()
Setup facet connectivity for tetgen.
virtual bool is_on_boundary() const
Test whether the Node lies on a boundary. The "bulk" Node cannot lie on a boundary, so return false. This will be overloaded by BoundaryNodes.
void setup_boundary_coordinates(const unsigned &b, std::ofstream &outfile)
Setup boundary coordinate on boundary b which is assumed to be planar. Boundary coordinates are the x...
unsigned One_based_region_id_that_facet_is_embedded_in
Facet is to be embedded in specified one-based region. Defaults to zero, indicating that its not embe...
TetMeshBase()
Constructor.
std::set< unsigned > One_based_boundary_id
Set of (one-based!) boundary IDs this vertex lives on.
double vertex_coordinate(const unsigned &j, const unsigned &i) const
i-th coordinate of j-th vertex
unsigned nregion_element(const unsigned &r)
Return the number of elements in region r.
TetMeshFacetedSurface()
Constructor:
Vector< double > Region_attribute
Vector of attributes associated with the elements in each region NOTE: double is enforced on us by te...
virtual ~TetMeshFacetedClosedSurface()
Empty destructor.
unsigned nvertex_on_facet(const unsigned &j) const
Number of vertices defining the j-th facet.
TetMeshVertex * vertex_pt(const unsigned &j) const
Pointer to j-th vertex (const)
unsigned nnode() const
Return the number of nodes.
Vector< double > zeta_in_geom_object() const
Get intrinisic coordinates in GeomObject (returns zero sized vector if no such coordinates have been ...
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
FiniteElement * region_element_pt(const unsigned &r, const unsigned &e)
Return the e-th element in the r-th region.
void set_one_based_boundary_id(const unsigned &id)
Set of (one-based!) boundary IDs this vertex lives on.
Vector< TetMeshFacetedSurface * > Internal_surface_pt
Vector to faceted surfaces that define internal boundaries.
std::map< unsigned, TetMeshFacet * > Tet_mesh_facet_pt
Reverse lookup scheme: Pointer to facet (if any!) associated with boundary b.
unsigned ninternal_point_for_tetgen()
Number of internal points (identifying either regions or holes) for tetgen.
TetMeshBase(const TetMeshBase &node)
Broken copy constructor.
unsigned nboundary_element_in_region(const unsigned &b, const unsigned &r) const
Return the number of elements adjacent to boundary b in region r.
unsigned one_based_boundary_id() const
Constant access to (one-based!) boundary IDs this facet lives on.
void disable_boundaries_can_be_split_in_tetgen()
Test whether boundaries can be split in tetgen.
const double & internal_point_for_tetgen(const unsigned &j, const unsigned &i) const
i=th coordinate of the j-th internal point for tetgen
void snap_to_quadratic_surface(const Vector< unsigned > &boundary_id, const std::string &quadratic_surface_file_name, const bool &switch_normal)
Snap boundaries specified by the IDs listed in boundary_id to a quadratric surface, specified in the file quadratic_surface_file_name. This is usually used with vmtk-based meshes for which oomph-lib's xda to poly conversion code produces the files "quadratic_fsi_boundary.dat" and "quadratic_outer_solid_boundary.dat" which specify the quadratic FSI boundary (for the fluid and the solid) and the quadratic representation of the outer boundary of the solid. When used with these files, the flag switch_normal should be set to true when calling the function for the outer boundary of the solid.
void disable_faceted_volume_represents_hole_for_gmsh()
Declare closed surface NOT to represent hole for gmsh.