51 std::ifstream element_file(element_file_name.c_str(),std::ios_base::in);
55 if(!element_file.is_open())
57 std::string error_msg(
"Failed to open element file: ");
58 error_msg +=
"\"" + element_file_name +
"\".";
60 OOMPH_EXCEPTION_LOCATION);
67 element_file>>n_element;
70 unsigned n_local_node;
71 element_file>>n_local_node;
76 std::ostringstream error_stream;
78 <<
"Tetgen should only be used to generate 4-noded tetrahedra!\n" 79 <<
"Your tetgen input file, contains data for " 80 << n_local_node <<
"-noded tetrahedra" << std::endl;
83 OOMPH_CURRENT_FUNCTION,
84 OOMPH_EXCEPTION_LOCATION);
88 unsigned dummy_attribute;
95 unsigned dummy_element_number;
103 unsigned attribute_flag;
104 element_file >> attribute_flag;
107 if(attribute_flag==0)
110 for(
unsigned i=0;
i<n_element;
i++)
112 element_file>>dummy_element_number;
113 for(
unsigned j=0;j<n_local_node;j++)
123 for(
unsigned i=0;
i<n_element;
i++)
125 element_file>>dummy_element_number;
126 for(
unsigned j=0;j<n_local_node;j++)
134 element_file.close();
141 std::ifstream node_file(node_file_name.c_str(),std::ios_base::in);
145 if(!node_file.is_open())
147 std::string error_msg(
"Failed to open node file: ");
148 error_msg +=
"\"" + node_file_name +
"\".";
150 OOMPH_EXCEPTION_LOCATION);
160 std::vector<bool> done (n_node,
false);
167 node_file>>dimension;
173 OOMPH_CURRENT_FUNCTION,
174 OOMPH_EXCEPTION_LOCATION);
179 node_file>>attribute_flag;
182 unsigned boundary_markers_flag;
183 node_file>>boundary_markers_flag;
186 unsigned dummy_node_number;
196 if(attribute_flag==0)
199 if(boundary_markers_flag==1)
201 for(
unsigned i=0;
i<n_node;
i++)
203 node_file>>dummy_node_number;
204 node_file>>x_node[
i];
205 node_file>>y_node[
i];
206 node_file>>z_node[
i];
214 for(
unsigned i=0;
i<n_node;
i++)
216 node_file>>dummy_node_number;
217 node_file>>x_node[
i];
218 node_file>>y_node[
i];
219 node_file>>z_node[
i];
228 if(boundary_markers_flag==1)
230 for(
unsigned i=0;
i<n_node;
i++)
232 node_file>>dummy_node_number;
233 node_file>>x_node[
i];
234 node_file>>y_node[
i];
235 node_file>>z_node[
i];
236 node_file>>dummy_attribute;
243 for(
unsigned i=0;
i<n_node;
i++)
245 node_file>>dummy_node_number;
246 node_file>>x_node[
i];
247 node_file>>y_node[
i];
248 node_file>>z_node[
i];
249 node_file>>dummy_attribute;
259 if(boundary_markers_flag==1)
262 for(
unsigned i=1;
i<n_node;
i++)
264 if(bound[
i] > n_bound)
275 std::ifstream face_file(face_file_name.c_str(),std::ios_base::in);
279 if(!face_file.is_open())
281 std::string error_msg(
"Failed to open face file: ");
282 error_msg +=
"\"" + face_file_name +
"\".";
284 OOMPH_EXCEPTION_LOCATION);
293 face_file>>boundary_markers_flag;
306 unsigned dummy_face_number;
314 for(
unsigned i=0;
i<n_face;
i++)
316 face_file >> dummy_face_number;
317 face_file >> first_node[
i];
318 face_file >> second_node[
i];
319 face_file >> third_node[
i];
320 face_file >> face_boundary[
i];
321 if (face_boundary[
i]>n_bound) {n_bound=face_boundary[
i];}
323 node_on_faces[first_node[
i]].insert(
i);
324 node_on_faces[second_node[
i]].insert(
i);
325 node_on_faces[third_node[
i]].insert(
i);
337 for(
unsigned e=0;
e<n_element;
e++)
341 if(done[global_node_number-1]==
false)
345 if((boundary_markers_flag==1) &&
346 (bound[global_node_number-1] > 0))
349 Node_pt[global_node_number-1] =
354 Node_pt[global_node_number-1]);
359 Node_pt[global_node_number-1] =
363 done[global_node_number-1]=
true;
364 Node_pt[global_node_number-1]->x(0)=x_node[global_node_number-1];
365 Node_pt[global_node_number-1]->x(1)=y_node[global_node_number-1];
366 Node_pt[global_node_number-1]->x(2)=z_node[global_node_number-1];
376 for(
unsigned j=0;j<(n_local_node-1);j++)
379 if(done[global_node_number-1]==
false)
383 if((boundary_markers_flag==1) &&
384 (bound[global_node_number-1] > 0))
387 Node_pt[global_node_number-1] =
392 Node_pt[global_node_number-1]);
398 done[global_node_number-1]=
true;
399 Node_pt[global_node_number-1]->x(0)=x_node[global_node_number-1];
400 Node_pt[global_node_number-1]->x(1)=y_node[global_node_number-1];
401 Node_pt[global_node_number-1]->x(2)=z_node[global_node_number-1];
438 const unsigned first_local_edge_node[6] = {0,0,0,1,2,1};
439 const unsigned second_local_edge_node[6] = {1,2,3,2,3,3};
442 for(
unsigned e=0;
e<n_element;
e++)
448 for(
unsigned i=0;
i<4;
i++)
458 const unsigned element_offset =
e*n_local_node;
459 unsigned glob_num[4] = {0,0,0,0};
460 for(
unsigned i=0;
i<4;++
i)
474 for(
unsigned i=0;
i<4;++
i)
478 const unsigned omitted_node = 3-
i;
482 std::set<unsigned> input = node_on_faces[glob_num[
i]];
489 unsigned local_node =
i;
490 for(
unsigned i2=0;i2<3;++i2)
493 local_node = (local_node+1)%4;
496 if(local_node != omitted_node)
499 std::set<unsigned> intersection_result;
502 std::set_intersection(input.begin(),input.end(),
503 node_on_faces[glob_num[local_node]].begin(),
504 node_on_faces[glob_num[local_node]].end(),
505 std::insert_iterator<std::set<unsigned> >(
507 intersection_result.begin()));
509 input = intersection_result;
519 "Nodes in scaffold mesh share more than one global face",
520 OOMPH_CURRENT_FUNCTION,
521 OOMPH_EXCEPTION_LOCATION);
531 for(
unsigned i2=0;i2<4;++i2)
534 if(i2 != omitted_node)
543 else if(input.size()==1)
545 const unsigned global_face_index = *input.begin();
549 if(global_face_index < n_face)
554 for(
unsigned i2=0;i2<4;++i2)
557 if(i2 != omitted_node)
569 for(
unsigned i=0;
i<6;++
i)
572 std::vector<unsigned> local_edge_index;
574 const unsigned first_global_num = glob_num[first_local_edge_node[
i]];
575 const unsigned second_global_num = glob_num[second_local_edge_node[
i]];
579 std::set_intersection(node_on_edges[first_global_num].begin(),
580 node_on_edges[first_global_num].end(),
581 node_on_edges[second_global_num].begin(),
582 node_on_edges[second_global_num].end(),
583 std::insert_iterator<std::vector<unsigned> >(
584 local_edge_index,local_edge_index.begin()));
588 if(local_edge_index.size() > 1)
591 "Nodes in scaffold mesh share more than one global edge",
592 OOMPH_CURRENT_FUNCTION,
593 OOMPH_EXCEPTION_LOCATION);
598 if(local_edge_index.size()==0)
609 else if(local_edge_index.size()==1)
628 for(
unsigned i=0;
i<n_face;++
i)
632 std::vector<unsigned> local_edge_index;
635 std::set_intersection(node_on_edges[first_node[
i]].begin(),
636 node_on_edges[first_node[
i]].end(),
637 node_on_edges[second_node[
i]].begin(),
638 node_on_edges[second_node[
i]].end(),
639 std::insert_iterator<std::vector<unsigned> >(
640 local_edge_index,local_edge_index.begin()));
644 if(local_edge_index.size() != 1)
647 "Nodes in scaffold mesh face do not share exactly one global edge",
648 OOMPH_CURRENT_FUNCTION,
649 OOMPH_EXCEPTION_LOCATION);
659 std::vector<unsigned> local_edge_index;
662 std::set_intersection(node_on_edges[second_node[
i]].begin(),
663 node_on_edges[second_node[
i]].end(),
664 node_on_edges[third_node[
i]].begin(),
665 node_on_edges[third_node[
i]].end(),
666 std::insert_iterator<std::vector<unsigned> >(
667 local_edge_index,local_edge_index.begin()));
671 if(local_edge_index.size() != 1)
674 "Nodes in scaffold mesh face do not share exactly one global edge",
675 OOMPH_CURRENT_FUNCTION,
676 OOMPH_EXCEPTION_LOCATION);
686 std::vector<unsigned> local_edge_index;
689 std::set_intersection(node_on_edges[first_node[
i]].begin(),
690 node_on_edges[first_node[
i]].end(),
691 node_on_edges[third_node[
i]].begin(),
692 node_on_edges[third_node[
i]].end(),
693 std::insert_iterator<std::vector<unsigned> >(
694 local_edge_index,local_edge_index.begin()));
698 if(local_edge_index.size() != 1)
701 "Nodes in scaffold mesh face do not share exactly one global edge",
702 OOMPH_CURRENT_FUNCTION,
703 OOMPH_EXCEPTION_LOCATION);
727 unsigned n_element =
static_cast<unsigned>(tetgen_data.numberoftetrahedra);
730 unsigned n_local_node =
static_cast<unsigned>(tetgen_data.numberofcorners);
735 std::ostringstream error_stream;
737 <<
"Tetgen should only be used to generate 4-noded tetrahedra!\n" 738 <<
"Your tetgen input data, contains data for " 739 << n_local_node <<
"-noded tetrahedra" << std::endl;
742 OOMPH_CURRENT_FUNCTION,
743 OOMPH_EXCEPTION_LOCATION);
756 unsigned attribute_flag =
757 static_cast<unsigned>(tetgen_data.numberoftetrahedronattributes);
760 if(attribute_flag==0)
762 for(
unsigned i=0;
i<n_element;
i++)
764 for(
unsigned j=0;j<n_local_node;j++)
766 Global_node[k] =
static_cast<unsigned>(tetgen_data.tetrahedronlist[k]);
774 for(
unsigned i=0;
i<n_element;
i++)
776 for(
unsigned j=0;j<n_local_node;j++)
778 Global_node[k] =
static_cast<unsigned>(tetgen_data.tetrahedronlist[k]);
789 unsigned n_node = tetgen_data.numberofpoints;
792 std::vector<bool> done (n_node,
false);
798 unsigned boundary_markers_flag = 0;
799 if(tetgen_data.pointmarkerlist!=0) {boundary_markers_flag=1;}
808 if(boundary_markers_flag==1)
810 for(
unsigned i=0;
i<n_node;
i++)
812 x_node[
i] = tetgen_data.pointlist[3*
i];
813 y_node[
i] = tetgen_data.pointlist[3*
i+1];
814 z_node[
i] = tetgen_data.pointlist[3*
i+2];
815 bound[
i] =
static_cast<unsigned>(tetgen_data.pointmarkerlist[
i]);
821 for(
unsigned i=0;
i<n_node;
i++)
823 x_node[
i] = tetgen_data.pointlist[3*
i];
824 y_node[
i] = tetgen_data.pointlist[3*
i+1];
825 z_node[
i] = tetgen_data.pointlist[3*
i+2];
834 if(boundary_markers_flag==1)
837 for(
unsigned i=1;
i<n_node;
i++)
839 if(bound[
i] > n_bound)
850 unsigned n_face = tetgen_data.numberoftrifaces;
868 for(
unsigned i=0;
i<n_face;
i++)
870 first_node[
i] =
static_cast<unsigned>(tetgen_data.trifacelist[3*
i]);
871 second_node[
i] =
static_cast<unsigned>(tetgen_data.trifacelist[3*
i+1]);
872 third_node[
i] =
static_cast<unsigned>(tetgen_data.trifacelist[3*
i+2]);
874 static_cast<unsigned>(tetgen_data.trifacemarkerlist[
i]);
875 if (face_boundary[
i]>n_bound) {n_bound=face_boundary[
i];}
877 node_on_faces[first_node[
i]].insert(
i);
878 node_on_faces[second_node[
i]].insert(
i);
879 node_on_faces[third_node[
i]].insert(
i);
919 for(
unsigned e=0;
e<n_element;
e++)
923 if(done[global_node_number-1]==
false)
927 if((boundary_markers_flag==1) &&
928 (bound[global_node_number-1] > 0))
931 Node_pt[global_node_number-1] =
936 Node_pt[global_node_number-1]);
941 Node_pt[global_node_number-1] =
945 done[global_node_number-1]=
true;
946 Node_pt[global_node_number-1]->x(0)=x_node[global_node_number-1];
947 Node_pt[global_node_number-1]->x(1)=y_node[global_node_number-1];
948 Node_pt[global_node_number-1]->x(2)=z_node[global_node_number-1];
958 for(
unsigned j=0;j<(n_local_node-1);j++)
961 if(done[global_node_number-1]==
false)
965 if((boundary_markers_flag==1) &&
966 (bound[global_node_number-1] > 0))
969 Node_pt[global_node_number-1] =
974 Node_pt[global_node_number-1]);
980 done[global_node_number-1]=
true;
981 Node_pt[global_node_number-1]->x(0)=x_node[global_node_number-1];
982 Node_pt[global_node_number-1]->x(1)=y_node[global_node_number-1];
983 Node_pt[global_node_number-1]->x(2)=z_node[global_node_number-1];
1020 const unsigned first_local_edge_node[6] = {0,0,0,1,2,1};
1021 const unsigned second_local_edge_node[6] = {1,2,3,2,3,3};
1024 for(
unsigned e=0;
e<n_element;
e++)
1030 for(
unsigned i=0;
i<4;
i++)
1040 const unsigned element_offset =
e*n_local_node;
1041 unsigned glob_num[4] = {0,0,0,0};
1042 for(
unsigned i=0;
i<4;++
i)
1056 for(
unsigned i=0;
i<4;++
i)
1060 const unsigned omitted_node = 3-
i;
1064 std::set<unsigned> input = node_on_faces[glob_num[
i]];
1068 if(input.size() > 0)
1071 unsigned local_node =
i;
1072 for(
unsigned i2=0;i2<3;++i2)
1075 local_node = (local_node+1)%4;
1078 if(local_node != omitted_node)
1081 std::set<unsigned> intersection_result;
1084 std::set_intersection(input.begin(),input.end(),
1085 node_on_faces[glob_num[local_node]].begin(),
1086 node_on_faces[glob_num[local_node]].end(),
1087 std::insert_iterator<std::set<unsigned> >(
1088 intersection_result,
1089 intersection_result.begin()));
1091 input = intersection_result;
1098 if(input.size() > 1)
1101 "Nodes in scaffold mesh share more than one global face",
1102 OOMPH_CURRENT_FUNCTION,
1103 OOMPH_EXCEPTION_LOCATION);
1113 for(
unsigned i2=0;i2<4;++i2)
1116 if(i2 != omitted_node)
1125 else if(input.size()==1)
1127 const unsigned global_face_index = *input.begin();
1131 if(global_face_index < n_face)
1136 for(
unsigned i2=0;i2<4;++i2)
1139 if(i2 != omitted_node)
1151 for(
unsigned i=0;
i<6;++
i)
1154 std::vector<unsigned> local_edge_index;
1156 const unsigned first_global_num = glob_num[first_local_edge_node[
i]];
1157 const unsigned second_global_num = glob_num[second_local_edge_node[
i]];
1161 std::set_intersection(node_on_edges[first_global_num].begin(),
1162 node_on_edges[first_global_num].end(),
1163 node_on_edges[second_global_num].begin(),
1164 node_on_edges[second_global_num].end(),
1165 std::insert_iterator<std::vector<unsigned> >(
1166 local_edge_index,local_edge_index.begin()));
1170 if(local_edge_index.size() > 1)
1173 "Nodes in scaffold mesh share more than one global edge",
1174 OOMPH_CURRENT_FUNCTION,
1175 OOMPH_EXCEPTION_LOCATION);
1180 if(local_edge_index.size()==0)
1191 else if(local_edge_index.size()==1)
1209 for(
unsigned i=0;
i<n_face;++
i)
1213 std::vector<unsigned> local_edge_index;
1216 std::set_intersection(node_on_edges[first_node[
i]].begin(),
1217 node_on_edges[first_node[
i]].end(),
1218 node_on_edges[second_node[
i]].begin(),
1219 node_on_edges[second_node[
i]].end(),
1220 std::insert_iterator<std::vector<unsigned> >(
1221 local_edge_index,local_edge_index.begin()));
1225 if(local_edge_index.size() != 1)
1228 "Nodes in scaffold mesh face do not share exactly one global edge",
1229 OOMPH_CURRENT_FUNCTION,
1230 OOMPH_EXCEPTION_LOCATION);
1240 std::vector<unsigned> local_edge_index;
1243 std::set_intersection(node_on_edges[second_node[
i]].begin(),
1244 node_on_edges[second_node[
i]].end(),
1245 node_on_edges[third_node[
i]].begin(),
1246 node_on_edges[third_node[
i]].end(),
1247 std::insert_iterator<std::vector<unsigned> >(
1248 local_edge_index,local_edge_index.begin()));
1252 if(local_edge_index.size() != 1)
1255 "Nodes in scaffold mesh face do not share exactly one global edge",
1256 OOMPH_CURRENT_FUNCTION,
1257 OOMPH_EXCEPTION_LOCATION);
1267 std::vector<unsigned> local_edge_index;
1270 std::set_intersection(node_on_edges[first_node[
i]].begin(),
1271 node_on_edges[first_node[
i]].end(),
1272 node_on_edges[third_node[
i]].begin(),
1273 node_on_edges[third_node[
i]].end(),
1274 std::insert_iterator<std::vector<unsigned> >(
1275 local_edge_index,local_edge_index.begin()));
1279 if(local_edge_index.size() != 1)
1282 "Nodes in scaffold mesh face do not share exactly one global edge",
1283 OOMPH_CURRENT_FUNCTION,
1284 OOMPH_EXCEPTION_LOCATION);
unsigned global_node_number(const unsigned &i)
Return the global node of each local node listed element-by-element e*n_local_node + n_local Note tha...
Vector< Node * > Node_pt
Vector of pointers to nodes.
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
unsigned Nglobal_face
Storage for the number of global faces.
Vector< Vector< unsigned > > Face_boundary
Vector of vectors containing the boundary ids of the elements' faces.
Vector< Vector< unsigned > > Edge_index
Vector of vectors containing the global edge index of.
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...
TetgenScaffoldMesh()
Empty constructor.
unsigned Nglobal_edge
Storage for the number of global edges.
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object. ...
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Vector< double > Element_attribute
Vector of double attributes for each element. NOTE: This stores doubles because tetgen forces us to! ...
Vector< unsigned > Global_node
Storage for global node numbers listed element-by-element.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
unsigned face_boundary(const unsigned &e, const unsigned &i) const
Return the boundary id of the i-th face in the e-th element: This is zero-based as in tetgen...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Vector< Vector< unsigned > > Face_index
Vector of vectors containing the global edge index of.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
std::vector< bool > Edge_boundary
Vector of booleans to indicate whether a global edge lies on a boundary.