26 #ifndef OOMPH_TETGEN_MESH_TEMPLATE_CC
27 #define OOMPH_TETGEN_MESH_TEMPLATE_CC
33 #include "../generic/Telements.h"
34 #include "../generic/map_matrix.h"
47 template<
class ELEMENT>
49 const bool& use_attributes)
52 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
55 unsigned nelem = Tmp_mesh_pt->nelement();
56 Element_pt.resize(nelem);
59 unsigned nnode_scaffold = Tmp_mesh_pt->nnode();
60 Node_pt.resize(nnode_scaffold);
63 unsigned nbound = Tmp_mesh_pt->nboundary();
64 set_nboundary(nbound);
65 Boundary_element_pt.resize(nbound);
66 Face_index_at_boundary.resize(nbound);
72 Boundary_region_element_pt.resize(nbound);
73 Face_index_region_at_boundary.resize(nbound);
77 for (
unsigned e = 0; e < nelem; e++)
79 Element_pt[e] =
new ELEMENT;
83 unsigned nnod_el = Tmp_mesh_pt->finite_element_pt(0)->nnode();
88 std::map<Node*, unsigned> global_number;
89 unsigned global_count = 0;
92 std::map<double, Vector<FiniteElement*>> element_attribute_map;
95 for (
unsigned e = 0; e < nelem; e++)
98 for (
unsigned j = 0; j < nnod_el; j++)
101 Node* scaffold_node_pt = Tmp_mesh_pt->finite_element_pt(e)->node_pt(j);
105 unsigned j_global = global_number[scaffold_node_pt];
112 std::set<unsigned>* boundaries_pt;
113 scaffold_node_pt->get_boundaries_pt(boundaries_pt);
116 if (boundaries_pt != 0)
120 finite_element_pt(e)->construct_boundary_node(j, time_stepper_pt);
126 global_number[scaffold_node_pt] = global_count;
129 for (std::set<unsigned>::iterator it = boundaries_pt->begin();
130 it != boundaries_pt->end();
133 add_boundary_node(*it, new_node_pt);
140 finite_element_pt(e)->construct_node(j, time_stepper_pt);
146 global_number[scaffold_node_pt] = global_count;
153 Node_pt[global_count - 1] = finite_element_pt(e)->node_pt(j);
156 Node_pt[global_count - 1]->x(0) = scaffold_node_pt->x(0);
157 Node_pt[global_count - 1]->x(1) = scaffold_node_pt->x(1);
158 Node_pt[global_count - 1]->x(2) = scaffold_node_pt->x(2);
163 finite_element_pt(e)->node_pt(j) = Node_pt[j_global - 1];
170 element_attribute_map[Tmp_mesh_pt->element_attribute(e)].push_back(
171 finite_element_pt(e));
179 unsigned n_attribute = element_attribute_map.size();
181 Region_element_pt.resize(n_attribute);
182 Region_attribute.resize(n_attribute);
185 for (std::map<
double, Vector<FiniteElement*>>::iterator it =
186 element_attribute_map.begin();
187 it != element_attribute_map.end();
190 Region_attribute[count] = it->first;
191 Region_element_pt[count] = it->second;
199 unsigned boundary_id;
203 unsigned n_node_1d = finite_element_pt(0)->nnode_1d();
206 if ((n_node_1d != 2) && (n_node_1d != 3))
208 std::ostringstream error_message;
209 error_message <<
"Mesh generation from tetgen currently only works\n";
210 error_message <<
"for nnode_1d = 2 or 3. You're trying to use it\n";
211 error_message <<
"for nnode_1d=" << n_node_1d << std::endl;
214 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
218 unsigned dim = finite_element_pt(0)->dim();
221 Vector<double> s(dim);
224 unsigned n_node = finite_element_pt(0)->nnode();
227 unsigned n_global_edge = Tmp_mesh_pt->nglobal_edge();
228 Vector<Vector<Node*>> nodes_on_global_edge(n_global_edge);
231 unsigned n_global_face = Tmp_mesh_pt->nglobal_face();
232 Vector<Vector<Node*>> nodes_on_global_face(n_global_face);
246 unsigned face_map[4] = {1, 0, 2, 3};
249 const unsigned faces_on_edge[6][2] = {
250 {0, 1}, {0, 2}, {1, 2}, {0, 3}, {2, 3}, {1, 3}};
253 for (
unsigned e = 0; e < nelem; e++)
256 FiniteElement*
const elem_pt = this->finite_element_pt(e);
257 FiniteElement*
const tmp_elem_pt = Tmp_mesh_pt->finite_element_pt(e);
260 unsigned n_edge_node = 4 + 6 * (n_node_1d - 2);
275 for (
unsigned j = 0; j < 6; ++j)
278 unsigned edge_index = Tmp_mesh_pt->edge_index(e, j);
282 std::set<unsigned> edge_boundaries;
283 for (
unsigned i = 0; i < 2; ++i)
285 unsigned face_boundary_id =
286 Tmp_mesh_pt->face_boundary(e, faces_on_edge[j][i]);
287 if (face_boundary_id > 0)
289 edge_boundaries.insert(face_boundary_id);
294 if (nodes_on_global_edge[edge_index].size() == 0)
297 for (
unsigned j2 = 0; j2 < n_node_1d - 2; ++j2)
300 Node* new_node_pt = 0;
307 if (Tmp_mesh_pt->edge_boundary(edge_index) ==
true)
310 elem_pt->construct_boundary_node(n, time_stepper_pt);
314 for (std::set<unsigned>::iterator it = edge_boundaries.begin();
315 it != edge_boundaries.end();
318 this->add_boundary_node((*it) - 1, new_node_pt);
324 new_node_pt = elem_pt->construct_node(n, time_stepper_pt);
328 elem_pt->local_coordinate_of_node(n, s);
332 for (
unsigned i = 0; i < dim; ++i)
334 new_node_pt->x(i) = tmp_elem_pt->interpolated_x(s, i);
338 Node_pt.push_back(new_node_pt);
340 nodes_on_global_edge[edge_index].push_back(new_node_pt);
348 for (
unsigned j2 = 0; j2 < n_node_1d - 2; ++j2)
350 elem_pt->node_pt(n) = nodes_on_global_edge[edge_index][j2];
355 for (std::set<unsigned>::iterator it = edge_boundaries.begin();
356 it != edge_boundaries.end();
359 this->add_boundary_node((*it) - 1, elem_pt->node_pt(n));
370 for (
unsigned j = 0; j < 4; ++j)
374 boundary_id = Tmp_mesh_pt->face_boundary(e, face_map[j]);
378 unsigned face_index = Tmp_mesh_pt->face_index(e, face_map[j]);
381 if (nodes_on_global_face[face_index].size() == 0)
384 Node* new_node_pt = 0;
390 elem_pt->construct_boundary_node(n, time_stepper_pt);
392 this->add_boundary_node(boundary_id - 1, new_node_pt);
397 new_node_pt = elem_pt->construct_node(n, time_stepper_pt);
401 elem_pt->local_coordinate_of_node(n, s);
405 for (
unsigned i = 0; i < dim; ++i)
407 new_node_pt->x(i) = tmp_elem_pt->interpolated_x(s, i);
411 Node_pt.push_back(new_node_pt);
413 nodes_on_global_face[face_index].push_back(new_node_pt);
420 elem_pt->node_pt(n) = nodes_on_global_face[face_index][0];
428 finite_element_pt(e)->construct_node(n, time_stepper_pt);
429 Node_pt.push_back(new_node_pt);
432 elem_pt->local_coordinate_of_node(n, s);
436 for (
unsigned i = 0; i < dim; i++)
438 new_node_pt->x(i) = tmp_elem_pt->interpolated_x(s, i);
448 for (
unsigned j = 0; j < 4; ++j)
451 boundary_id = Tmp_mesh_pt->face_boundary(e, j);
455 Boundary_element_pt[boundary_id - 1].push_back(elem_pt);
462 Face_index_at_boundary[boundary_id - 1].push_back(3 - j);
468 Boundary_region_element_pt[boundary_id - 1]
469 [
static_cast<unsigned>(
470 Tmp_mesh_pt->element_attribute(e))]
474 Face_index_region_at_boundary[boundary_id - 1]
475 [
static_cast<unsigned>(
476 Tmp_mesh_pt->element_attribute(e))]
484 Lookup_for_elements_next_boundary_is_setup =
true;
827 template<
class ELEMENT>
829 TetMeshFacetedSurface*
const& faceted_surface_pt)
833 unsigned n_facet = faceted_surface_pt->nfacet();
834 for (
unsigned f = 0; f < n_facet; f++)
836 unsigned b = faceted_surface_pt->one_based_facet_boundary_id(f);
839 this->Tet_mesh_faceted_surface_pt[b - 1] = faceted_surface_pt;
840 this->Tet_mesh_facet_pt[b - 1] = faceted_surface_pt->facet_pt(f);
844 std::ostringstream error_message;
845 error_message <<
"Boundary IDs have to be one-based. Yours is " << b
847 throw OomphLibError(error_message.str(),
848 OOMPH_CURRENT_FUNCTION,
849 OOMPH_EXCEPTION_LOCATION);
864 template<
class ELEMENT>
866 tetgenio*& output_pt)
869 output_pt->firstnumber = input_pt->firstnumber;
870 output_pt->mesh_dim = input_pt->mesh_dim;
871 output_pt->useindex = input_pt->useindex;
874 output_pt->numberofpoints = input_pt->numberofpoints;
875 output_pt->numberofpointattributes = input_pt->numberofpointattributes;
876 output_pt->numberofpointmtrs = input_pt->numberofpointmtrs;
878 const int n_point = output_pt->numberofpoints;
881 output_pt->pointlist =
new double[n_point * 3];
883 for (
int n = 0; n < (n_point * 3); ++n)
885 output_pt->pointlist[n] = input_pt->pointlist[n];
889 if (input_pt->pointmarkerlist != (
int*)NULL)
891 output_pt->pointmarkerlist =
new int[n_point];
892 for (
int n = 0; n < n_point; ++n)
894 output_pt->pointmarkerlist[n] = input_pt->pointmarkerlist[n];
898 const int n_attr = output_pt->numberofpointattributes;
901 output_pt->pointattributelist =
new double[n_point * n_attr];
902 for (
int n = 0; n < (n_point * n_attr); ++n)
904 output_pt->pointattributelist[n] = input_pt->pointattributelist[n];
910 const int n_point_mtr = output_pt->numberofpointmtrs;
913 output_pt->pointmtrlist =
new double[n_point * n_point_mtr];
914 for (
int n = 0; n < (n_point * n_point_mtr); ++n)
916 output_pt->pointmtrlist[n] = input_pt->pointmtrlist[n];
921 output_pt->numberoftetrahedra = input_pt->numberoftetrahedra;
922 output_pt->numberofcorners = input_pt->numberofcorners;
923 output_pt->numberoftetrahedronattributes =
924 input_pt->numberoftetrahedronattributes;
926 const int n_tetra = output_pt->numberoftetrahedra;
927 const int n_corner = output_pt->numberofcorners;
930 output_pt->tetrahedronlist =
new int[n_tetra * n_corner];
931 for (
int n = 0; n < (n_tetra * n_corner); ++n)
933 output_pt->tetrahedronlist[n] = input_pt->tetrahedronlist[n];
937 if (input_pt->tetrahedronvolumelist != (
double*)NULL)
939 output_pt->tetrahedronvolumelist =
new double[n_tetra];
940 for (
int n = 0; n < n_tetra; ++n)
942 output_pt->tetrahedronvolumelist[n] =
943 input_pt->tetrahedronvolumelist[n];
948 const int n_tetra_attr = output_pt->numberoftetrahedronattributes;
949 if (n_tetra_attr > 0)
951 output_pt->tetrahedronattributelist =
952 new double[n_tetra * n_tetra_attr];
953 for (
int n = 0; n < (n_tetra * n_tetra_attr); ++n)
955 output_pt->tetrahedronattributelist[n] =
956 input_pt->tetrahedronattributelist[n];
961 if (input_pt->neighborlist != (
int*)NULL)
963 output_pt->neighborlist =
new int[n_tetra * 4];
964 for (
int n = 0; n < (n_tetra * 4); ++n)
966 output_pt->neighborlist = input_pt->neighborlist;
972 output_pt->numberoffacets = input_pt->numberoffacets;
973 const int n_facet = output_pt->numberoffacets;
976 output_pt->facetlist =
new tetgenio::facet[n_facet];
977 for (
int n = 0; n < n_facet; ++n)
979 tetgenio::facet* input_f_pt = &input_pt->facetlist[n];
980 tetgenio::facet* output_f_pt = &output_pt->facetlist[n];
983 output_f_pt->numberofpolygons = input_f_pt->numberofpolygons;
986 const int n_poly = output_f_pt->numberofpolygons;
989 output_f_pt->polygonlist =
new tetgenio::polygon[n_poly];
990 for (
int p = 0; p < n_poly; ++p)
992 tetgenio::polygon* output_p_pt = &output_f_pt->polygonlist[p];
993 tetgenio::polygon* input_p_pt = &input_f_pt->polygonlist[p];
995 output_p_pt->numberofvertices = input_p_pt->numberofvertices;
997 const int n_vertex = output_p_pt->numberofvertices;
1000 output_p_pt->vertexlist =
new int[n_vertex];
1001 for (
int v = 0; v < n_vertex; ++v)
1003 output_p_pt->vertexlist[v] = input_p_pt->vertexlist[v];
1010 output_f_pt->numberofholes = input_f_pt->numberofholes;
1011 const int n_hole = output_f_pt->numberofholes;
1014 throw OomphLibError(
"Don't know how to handle holes yet\n",
1015 OOMPH_CURRENT_FUNCTION,
1016 OOMPH_EXCEPTION_LOCATION);
1021 if (input_pt->facetmarkerlist != (
int*)NULL)
1023 output_pt->facetmarkerlist =
new int[n_facet];
1024 for (
int n = 0; n < n_facet; ++n)
1026 output_pt->facetmarkerlist[n] = input_pt->facetmarkerlist[n];
1032 output_pt->numberofholes = input_pt->numberofholes;
1033 const int n_hole = output_pt->numberofholes;
1036 output_pt->holelist =
new double[n_hole * 3];
1037 for (
int n = 0; n < (n_hole * 3); ++n)
1039 output_pt->holelist[n] = input_pt->holelist[n];
1044 output_pt->numberofregions = input_pt->numberofregions;
1045 const int n_region = output_pt->numberofregions;
1048 output_pt->regionlist =
new double[n_region * 5];
1049 for (
int n = 0; n < (n_region * 5); ++n)
1051 output_pt->regionlist[n] = input_pt->regionlist[n];
1056 output_pt->numberoffacetconstraints = input_pt->numberoffacetconstraints;
1057 const int n_facet_const = output_pt->numberoffacetconstraints;
1058 if (n_facet_const > 0)
1060 output_pt->facetconstraintlist =
new double[n_facet_const * 2];
1061 for (
int n = 0; n < (n_facet_const * 2); ++n)
1063 output_pt->facetconstraintlist[n] = input_pt->facetconstraintlist[n];
1068 output_pt->numberofsegmentconstraints =
1069 input_pt->numberofsegmentconstraints;
1070 const int n_seg_const = output_pt->numberofsegmentconstraints;
1071 if (n_seg_const > 0)
1073 output_pt->segmentconstraintlist =
new double[n_seg_const * 2];
1074 for (
int n = 0; n < (n_seg_const * 2); ++n)
1076 output_pt->segmentconstraintlist[n] =
1077 input_pt->segmentconstraintlist[n];
1082 output_pt->numberoftrifaces = input_pt->numberoftrifaces;
1083 const int n_tri_face = output_pt->numberoftrifaces;
1086 output_pt->trifacelist =
new int[n_tri_face * 3];
1087 for (
int n = 0; n < (n_tri_face * 3); ++n)
1089 output_pt->trifacelist[n] = input_pt->trifacelist[n];
1092 output_pt->trifacemarkerlist =
new int[n_tri_face];
1093 for (
int n = 0; n < n_tri_face; ++n)
1095 output_pt->trifacemarkerlist[n] = input_pt->trifacemarkerlist[n];
1100 output_pt->numberofedges = input_pt->numberofedges;
1101 const int n_edge = output_pt->numberofedges;
1104 output_pt->edgelist =
new int[n_edge * 2];
1105 for (
int n = 0; n < (n_edge * 2); ++n)
1107 output_pt->edgelist[n] = input_pt->edgelist[n];
1110 output_pt->edgemarkerlist =
new int[n_edge];
1111 for (
int n = 0; n < n_edge; ++n)
1113 output_pt->edgemarkerlist[n] = input_pt->edgemarkerlist[n];
void build_from_scaffold(TimeStepper *time_stepper_pt, const bool &use_attributes)
Build mesh from scaffold.
void setup_reverse_lookup_schemes_for_faceted_surface(TetMeshFacetedSurface *const &faceted_surface_pt)
Function to setup the reverse look-up schemes.
void deep_copy_of_tetgenio(tetgenio *const &input_pt, tetgenio *&output_pt)
Transfer tetgenio data from the input to the output The output is assumed to have been constructed an...
////////////////////////////////////////////////////////////////////// //////////////////////////////...