30 #ifndef OOMPH_TETGEN_MESH_TEMPLATE_CC 31 #define OOMPH_TETGEN_MESH_TEMPLATE_CC 37 #include "../generic/Telements.h" 38 #include "../generic/map_matrix.h" 56 template <
class ELEMENT>
58 const bool &use_attributes)
61 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
64 unsigned nelem=Tmp_mesh_pt->nelement();
65 Element_pt.resize(nelem);
68 unsigned nnode_scaffold=Tmp_mesh_pt->nnode();
69 Node_pt.resize(nnode_scaffold);
72 unsigned nbound=Tmp_mesh_pt->nboundary();
73 set_nboundary(nbound);
74 Boundary_element_pt.resize(nbound);
75 Face_index_at_boundary.resize(nbound);
81 Boundary_region_element_pt.resize(nbound);
82 Face_index_region_at_boundary.resize(nbound);
86 for (
unsigned e=0;
e<nelem;
e++)
88 Element_pt[
e]=
new ELEMENT;
92 unsigned nnod_el=Tmp_mesh_pt->finite_element_pt(0)->nnode();
97 std::map<Node*,unsigned> global_number;
98 unsigned global_count=0;
101 std::map<double,Vector<FiniteElement*> > element_attribute_map;
104 for (
unsigned e=0;
e<nelem;
e++)
107 for (
unsigned j=0;j<nnod_el;j++)
111 Node* scaffold_node_pt=Tmp_mesh_pt->finite_element_pt(
e)->node_pt(j);
115 unsigned j_global=global_number[scaffold_node_pt];
122 std::set<unsigned>* boundaries_pt;
126 if (boundaries_pt!=0)
129 Node* new_node_pt=finite_element_pt(
e)->
130 construct_boundary_node(j,time_stepper_pt);
136 global_number[scaffold_node_pt]=global_count;
139 for(std::set<unsigned>::iterator it=boundaries_pt->begin();
140 it!=boundaries_pt->end();++it)
142 add_boundary_node(*it,new_node_pt);
149 finite_element_pt(
e)->construct_node(j,time_stepper_pt);
155 global_number[scaffold_node_pt]=global_count;
162 Node_pt[global_count-1]=finite_element_pt(
e)->node_pt(j);
165 Node_pt[global_count-1]->x(0)=scaffold_node_pt->
x(0);
166 Node_pt[global_count-1]->x(1)=scaffold_node_pt->
x(1);
167 Node_pt[global_count-1]->x(2)=scaffold_node_pt->
x(2);
173 finite_element_pt(
e)->node_pt(j)=Node_pt[j_global-1];
180 element_attribute_map[Tmp_mesh_pt->element_attribute(
e)].push_back(
181 finite_element_pt(
e));
189 unsigned n_attribute = element_attribute_map.size();
191 Region_element_pt.resize(n_attribute);
192 Region_attribute.resize(n_attribute);
196 element_attribute_map.begin(); it != element_attribute_map.end();++it)
198 Region_attribute[count] = it->first;
199 Region_element_pt[count] = it->second;
207 unsigned boundary_id;
211 unsigned n_node_1d=finite_element_pt(0)->nnode_1d();
214 if ((n_node_1d!=2)&&(n_node_1d!=3))
216 std::ostringstream error_message;
217 error_message <<
"Mesh generation from tetgen currently only works\n";
218 error_message <<
"for nnode_1d = 2 or 3. You're trying to use it\n";
219 error_message <<
"for nnode_1d=" << n_node_1d << std::endl;
222 OOMPH_CURRENT_FUNCTION,
223 OOMPH_EXCEPTION_LOCATION);
227 unsigned dim=finite_element_pt(0)->dim();
233 unsigned n_node=finite_element_pt(0)->nnode();
236 unsigned n_global_edge = Tmp_mesh_pt->nglobal_edge();
240 unsigned n_global_face = Tmp_mesh_pt->nglobal_face();
255 unsigned face_map[4] = {1,0,2,3};
258 const unsigned faces_on_edge[6][2]={
259 {0,1},{0,2},{1,2},{0,3},{2,3},{1,3}};
262 for(
unsigned e=0;
e<nelem;
e++)
266 FiniteElement*
const tmp_elem_pt = Tmp_mesh_pt->finite_element_pt(
e);
269 unsigned n_edge_node = 4 + 6*(n_node_1d-2);
284 for(
unsigned j=0;j<6;++j)
287 unsigned edge_index = Tmp_mesh_pt->edge_index(
e,j);
291 std::set<unsigned> edge_boundaries;
292 for(
unsigned i=0;
i<2;++
i)
294 unsigned face_boundary_id =
295 Tmp_mesh_pt->face_boundary(
e,faces_on_edge[j][
i]);
296 if(face_boundary_id > 0)
298 edge_boundaries.insert(face_boundary_id);
303 if(nodes_on_global_edge[edge_index].size()==0)
306 for(
unsigned j2=0;j2<n_node_1d-2;++j2)
309 Node* new_node_pt = 0;
316 if(Tmp_mesh_pt->edge_boundary(edge_index) ==
true)
323 for(std::set<unsigned>::iterator it = edge_boundaries.begin();
324 it!=edge_boundaries.end();++it)
326 this->add_boundary_node((*it)-1,new_node_pt);
341 for(
unsigned i=0;
i<dim;++
i)
347 Node_pt.push_back(new_node_pt);
349 nodes_on_global_edge[edge_index].push_back(new_node_pt);
357 for(
unsigned j2=0;j2<n_node_1d-2;++j2)
360 nodes_on_global_edge[edge_index][j2];
365 for(std::set<unsigned>::iterator it = edge_boundaries.begin();
366 it!=edge_boundaries.end();++it)
368 this->add_boundary_node((*it)-1,elem_pt->
node_pt(n));
379 for(
unsigned j=0;j<4;++j)
383 boundary_id = Tmp_mesh_pt->face_boundary(
e,face_map[j]);
387 unsigned face_index = Tmp_mesh_pt->face_index(
e,face_map[j]);
390 if(nodes_on_global_face[face_index].size()==0)
401 this->add_boundary_node(boundary_id-1,new_node_pt);
415 for(
unsigned i=0;
i<dim;++
i)
421 Node_pt.push_back(new_node_pt);
423 nodes_on_global_face[face_index].push_back(new_node_pt);
430 elem_pt->
node_pt(n) = nodes_on_global_face[face_index][0];
438 finite_element_pt(
e)->construct_node(n,time_stepper_pt);
439 Node_pt.push_back(new_node_pt);
446 for(
unsigned i=0;
i<dim;
i++)
458 for(
unsigned j=0;j<4;++j)
461 boundary_id = Tmp_mesh_pt->face_boundary(
e,j);
465 Boundary_element_pt[boundary_id-1].push_back(elem_pt);
472 Face_index_at_boundary[boundary_id-1].push_back(3-j);
478 Boundary_region_element_pt[boundary_id-1]
479 [
static_cast<unsigned>(Tmp_mesh_pt->element_attribute(
e))].
483 Face_index_region_at_boundary[boundary_id-1]
484 [
static_cast<unsigned>(Tmp_mesh_pt->element_attribute(
e))].
492 Lookup_for_elements_next_boundary_is_setup=
true;
844 template<
class ELEMENT>
846 tetgenio* &output_pt)
849 output_pt->firstnumber = input_pt->firstnumber;
850 output_pt->mesh_dim = input_pt->mesh_dim;
851 output_pt->useindex = input_pt->useindex;
854 output_pt->numberofpoints = input_pt->numberofpoints;
855 output_pt->numberofpointattributes = input_pt->numberofpointattributes;
856 output_pt->numberofpointmtrs = input_pt->numberofpointmtrs;
858 const int n_point = output_pt->numberofpoints;
861 output_pt->pointlist =
new double[n_point * 3];
863 for(
int n=0;n<(n_point * 3);++n)
865 output_pt->pointlist[n] = input_pt->pointlist[n];
869 if(input_pt->pointmarkerlist != (
int*) NULL)
871 output_pt->pointmarkerlist =
new int[n_point];
872 for(
int n=0;n<n_point;++n)
874 output_pt->pointmarkerlist[n] = input_pt->pointmarkerlist[n];
878 const int n_attr = output_pt->numberofpointattributes;
881 output_pt->pointattributelist =
new double[n_point * n_attr];
882 for(
int n=0;n<(n_point * n_attr);++n)
884 output_pt->pointattributelist[n] =
885 input_pt->pointattributelist[n];
891 const int n_point_mtr = output_pt->numberofpointmtrs;
894 output_pt->pointmtrlist =
new double[n_point * n_point_mtr];
895 for(
int n=0;n<(n_point * n_point_mtr);++n)
897 output_pt->pointmtrlist[n] = input_pt->pointmtrlist[n];
902 output_pt->numberoftetrahedra = input_pt->numberoftetrahedra;
903 output_pt->numberofcorners = input_pt->numberofcorners;
904 output_pt->numberoftetrahedronattributes =
905 input_pt->numberoftetrahedronattributes;
907 const int n_tetra = output_pt->numberoftetrahedra;
908 const int n_corner = output_pt->numberofcorners;
911 output_pt->tetrahedronlist =
new int[n_tetra * n_corner];
912 for(
int n=0;n<(n_tetra * n_corner);++n)
914 output_pt->tetrahedronlist[n] = input_pt->tetrahedronlist[n];
918 if(input_pt->tetrahedronvolumelist != (
double*) NULL)
920 output_pt->tetrahedronvolumelist =
new double[n_tetra];
921 for(
int n=0;n<n_tetra;++n)
923 output_pt->tetrahedronvolumelist[n] =
924 input_pt->tetrahedronvolumelist[n];
929 const int n_tetra_attr = output_pt->numberoftetrahedronattributes;
932 output_pt->tetrahedronattributelist =
new double[n_tetra * n_tetra_attr];
933 for(
int n=0;n<(n_tetra * n_tetra_attr);++n)
935 output_pt->tetrahedronattributelist[n] =
936 input_pt->tetrahedronattributelist[n];
941 if(input_pt->neighborlist != (
int*) NULL)
943 output_pt->neighborlist =
new int[n_tetra * 4];
944 for(
int n=0;n<(n_tetra * 4);++n)
946 output_pt->neighborlist = input_pt->neighborlist;
952 output_pt->numberoffacets = input_pt->numberoffacets;
953 const int n_facet = output_pt->numberoffacets;
956 output_pt->facetlist =
new tetgenio::facet[n_facet];
957 for(
int n=0;n<n_facet;++n)
959 tetgenio::facet *input_f_pt = &input_pt->facetlist[n];
960 tetgenio::facet *output_f_pt = &output_pt->facetlist[n];
963 output_f_pt->numberofpolygons = input_f_pt->numberofpolygons;
966 const int n_poly = output_f_pt->numberofpolygons;
969 output_f_pt->polygonlist =
new tetgenio::polygon[n_poly];
970 for(
int p=0;p<n_poly;++p)
972 tetgenio::polygon *output_p_pt = &output_f_pt->polygonlist[p];
973 tetgenio::polygon *input_p_pt = &input_f_pt->polygonlist[p];
975 output_p_pt->numberofvertices = input_p_pt->numberofvertices;
977 const int n_vertex = output_p_pt->numberofvertices;
980 output_p_pt->vertexlist =
new int[n_vertex];
981 for(
int v=0;v<n_vertex;++v)
983 output_p_pt->vertexlist[v] = input_p_pt->vertexlist[v];
990 output_f_pt->numberofholes = input_f_pt->numberofholes;
991 const int n_hole = output_f_pt->numberofholes;
995 OOMPH_CURRENT_FUNCTION,
996 OOMPH_EXCEPTION_LOCATION);
1001 if(input_pt->facetmarkerlist != (
int*) NULL)
1003 output_pt->facetmarkerlist =
new int[n_facet];
1004 for(
int n=0;n<n_facet;++n)
1006 output_pt->facetmarkerlist[n] = input_pt->facetmarkerlist[n];
1012 output_pt->numberofholes = input_pt->numberofholes;
1013 const int n_hole = output_pt->numberofholes;
1016 output_pt->holelist =
new double[n_hole * 3];
1017 for(
int n=0;n<(n_hole * 3);++n)
1019 output_pt->holelist[n] = input_pt->holelist[n];
1024 output_pt->numberofregions = input_pt->numberofregions;
1025 const int n_region = output_pt->numberofregions;
1028 output_pt->regionlist =
new double[n_region * 5];
1029 for(
int n=0;n<(n_region * 5);++n)
1031 output_pt->regionlist[n] = input_pt->regionlist[n];
1036 output_pt->numberoffacetconstraints = input_pt->numberoffacetconstraints;
1037 const int n_facet_const = output_pt->numberoffacetconstraints;
1038 if(n_facet_const > 0)
1040 output_pt->facetconstraintlist =
new double[n_facet_const * 2];
1041 for(
int n=0;n<(n_facet_const * 2);++n)
1043 output_pt->facetconstraintlist[n] = input_pt->facetconstraintlist[n];
1048 output_pt->numberofsegmentconstraints = input_pt->numberofsegmentconstraints;
1049 const int n_seg_const = output_pt->numberofsegmentconstraints;
1052 output_pt->segmentconstraintlist =
new double[n_seg_const * 2];
1053 for(
int n=0;n<(n_seg_const * 2);++n)
1055 output_pt->segmentconstraintlist[n] = input_pt->segmentconstraintlist[n];
1060 output_pt->numberoftrifaces = input_pt->numberoftrifaces;
1061 const int n_tri_face = output_pt->numberoftrifaces;
1064 output_pt->trifacelist =
new int[n_tri_face * 3];
1065 for(
int n=0;n<(n_tri_face * 3);++n)
1067 output_pt->trifacelist[n] = input_pt->trifacelist[n];
1070 output_pt->trifacemarkerlist =
new int[n_tri_face];
1071 for(
int n=0;n<n_tri_face;++n)
1073 output_pt->trifacemarkerlist[n] = input_pt->trifacemarkerlist[n];
1078 output_pt->numberofedges = input_pt->numberofedges;
1079 const int n_edge = output_pt->numberofedges;
1082 output_pt->edgelist =
new int[n_edge * 2];
1083 for(
int n=0;n<(n_edge * 2);++n)
1085 output_pt->edgelist[n] = input_pt->edgelist[n];
1088 output_pt->edgemarkerlist =
new int[n_edge];
1089 for(
int n=0;n<n_edge;++n)
1091 output_pt->edgemarkerlist[n] = input_pt->edgemarkerlist[n];
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size (broken virtual) ...
void build_from_scaffold(TimeStepper *time_stepper_pt, const bool &use_attributes)
Build mesh from scaffold.
A general Finite Element class.
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...
virtual void get_boundaries_pt(std::set< unsigned > *&boundaries_pt)
Return a pointer to set of mesh boundaries that this node occupies; this will be overloaded by Bounda...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object. ...
void deep_copy_of_tetgenio(tetgenio *const &input_pt, tetgenio *&output_pt)
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...