31 #ifndef OOMPH_GMSH_TET_MESH_HEADER 32 #define OOMPH_GMSH_TET_MESH_HEADER 36 #include <oomph-lib-config.h> 44 #include "../generic/sample_point_parameters.h" 45 #include "../generic/mesh_as_geometric_object.h" 46 #include "../generic/projection.h" 279 TetEdge(
const unsigned& vertex1,
const unsigned& vertex2)
284 Vertex_pair=std::make_pair(vertex2,vertex1);
286 else if (vertex1<vertex2)
289 Vertex_pair=std::make_pair(vertex1,vertex2);
294 "Muppet! You can't build an edge from one vertex to the same vertex!",
295 OOMPH_CURRENT_FUNCTION,
296 OOMPH_EXCEPTION_LOCATION);
304 return Vertex_pair.first;
310 return Vertex_pair.second;
323 bool operator ==(
const TetEdge& tet_edge)
const 331 bool operator < (
const TetEdge& tet_edge)
const 370 template<
class ELEMENT>
384 template<
class ELEMENT>
391 const bool& use_mesh_grading_from_file) :
392 Gmsh_parameters_pt(gmsh_parameters_pt)
398 write_geo_file(use_mesh_grading_from_file);
402 <<
" sec " << std::endl;
410 std::ofstream gmsh_on_screen_output_file;
411 std::stringstream marker;
412 if (gmsh_onscreen_output_file_name!=
"")
415 <<
"\n\n====================================================\n" 416 <<
" gmsh invocation: " 418 <<
"====================================================\n\n\n" 422 gmsh_on_screen_output_file.open(gmsh_onscreen_output_file_name.c_str(),
424 gmsh_on_screen_output_file << marker.str();
425 gmsh_on_screen_output_file.close();
428 gmsh_command_line_string +=
429 Gmsh_parameters_pt->gmsh_command_line_invocation() +
" " +
430 Gmsh_parameters_pt->geo_and_msh_file_stem() +
".geo -3";
431 if (gmsh_onscreen_output_file_name!=
"")
438 int return_flag=system(gmsh_command_line_string.c_str());
439 oomph_info <<
"fyi: return from system command: " << return_flag
443 <<
" sec " << std::endl;
448 create_mesh_from_msh_file();
450 oomph_info <<
"Time for creating mesh from msh file: " 452 <<
" sec " << std::endl;
483 std::ifstream mesh_file(mesh_file_name.c_str(),std::ios_base::in);
487 if(!mesh_file.is_open())
489 std::string error_msg(
"Failed to open mesh file: ");
490 error_msg +=
"\"" + mesh_file_name +
"\".";
492 OOMPH_CURRENT_FUNCTION,
493 OOMPH_EXCEPTION_LOCATION);
501 if (line!=
"$MeshFormat")
504 (
"First line has to contain the string \"$MeshFormat\"; ");
505 error_msg +=
" yours contains: " + line;
507 OOMPH_CURRENT_FUNCTION,
508 OOMPH_EXCEPTION_LOCATION);
519 bool keep_going=
true;
531 std::map<unsigned,Vector<double> > node_coordinate;
532 for (
unsigned j=0;j<nnod;j++)
534 unsigned node_number=0;
535 mesh_file >> node_number;
539 std::getline(mesh_file, s);
540 std::istringstream iss(s);
544 node_coordinate[node_number].push_back(atof(sub.c_str()));
549 if (line!=
"$EndNodes")
551 std::string error_msg(
"Line has to contain the string \"$EndNodes\"; ");
552 error_msg +=
" yours contains: " + line;
554 OOMPH_CURRENT_FUNCTION,
555 OOMPH_EXCEPTION_LOCATION);
563 if (line!=
"$MeshFormat")
566 (
"First line has to contain the string \"$MeshFormat\"; ");
567 error_msg +=
" yours contains: " + line;
569 OOMPH_CURRENT_FUNCTION,
570 OOMPH_EXCEPTION_LOCATION);
577 std::map<unsigned,std::set<unsigned> > one_based_boundaries_of_node;
583 std::map<unsigned,std::set<unsigned> > boundary_node;
586 std::map<unsigned,std::set<unsigned> > region_element;
594 if (line==
"$Elements")
601 unsigned highest_one_based_boundary_id=0;
606 std::map<unsigned,Vector<unsigned> > element_node_index;
607 for (
unsigned e=0;
e<nel;
e++)
621 unsigned el_number=0;
622 mesh_file >> el_number;
626 mesh_file >> el_type;
651 OOMPH_CURRENT_FUNCTION,
652 OOMPH_EXCEPTION_LOCATION);
662 mesh_file >> physical_tag;
666 mesh_file >> geom_tag;
669 for (
unsigned i=2;
i<ntags;
i++)
673 other_tags.push_back(tag);
680 std::getline(mesh_file,s);
681 std::istringstream iss(s);
686 other_ints.push_back(atoi(sub.c_str()));
688 unsigned n_el_nod=other_ints.size();
689 for (
unsigned j=0;j<n_el_nod;j++)
691 unsigned node_number=unsigned(other_ints[j]);
692 element_node_index[el_number].push_back(node_number);
700 boundary_node[unsigned(physical_tag)].insert(node_number);
701 one_based_boundaries_of_node[node_number].insert(
702 unsigned(physical_tag));
703 if (
unsigned(physical_tag)>highest_one_based_boundary_id)
705 highest_one_based_boundary_id=physical_tag;
716 region_element[unsigned(physical_tag)].insert(n_tet_el);
722 if (line!=
"$EndElements")
725 (
"Line has to contain the string \"$EndElements\"; ");
726 error_msg +=
" yours contains: " + line;
728 OOMPH_CURRENT_FUNCTION,
729 OOMPH_EXCEPTION_LOCATION);
737 if (line!=
"$MeshFormat")
740 (
"First line has to contain the string \"$MeshFormat\"; ");
741 error_msg +=
" yours contains: " + line;
743 OOMPH_CURRENT_FUNCTION,
744 OOMPH_EXCEPTION_LOCATION);
759 std::map<unsigned,std::set<unsigned> > element_next_to_boundary;
761 element_node_index.begin();it!=element_node_index.end();it++)
763 unsigned el_number=(*it).first;
764 unsigned nnod=((*it).second).size();
767 std::map<unsigned,unsigned> boundary_node_count;
768 for (
unsigned j=0;j<nnod;j++)
770 unsigned node_number=((*it).second)[j];
771 std::map<unsigned,std::set<unsigned> >::iterator itt=
772 one_based_boundaries_of_node.find(node_number);
773 if (itt!=one_based_boundaries_of_node.end())
775 for (std::set<unsigned>::iterator ittt=(itt->second).begin();
776 ittt!=(itt->second).end();ittt++)
778 unsigned one_based_boundary_id=(*ittt);
779 boundary_node_count[one_based_boundary_id]++;
783 for (std::map<unsigned,unsigned>::iterator
784 itt=boundary_node_count.begin();
785 itt!=boundary_node_count.end();itt++)
787 if ((*itt).second==3)
789 element_next_to_boundary[(*itt).first].insert(el_number);
795 this->set_nboundary(highest_one_based_boundary_id);
802 oomph_lib_node_number[0]=0;
803 oomph_lib_node_number[1]=3;
804 oomph_lib_node_number[2]=2;
805 oomph_lib_node_number[3]=1;
808 Element_pt.resize(n_tet_el);
809 Node_pt.resize(nnod);
817 element_node_index.begin();
818 it!=element_node_index.end();it++)
820 unsigned el_nnod=(*it).second.size();
831 for (
unsigned j=0;j<el_nnod;j++)
834 unsigned node_number=(*it).second[j];
837 if (existing_node_pt[node_number-1]!=0)
839 el_pt->node_pt(oomph_lib_node_number[j])=
840 existing_node_pt[node_number-1];
848 if (one_based_boundaries_of_node[node_number].size()==0)
851 nod_pt=el_pt->construct_node(oomph_lib_node_number[j]);
852 Node_pt[node_number-1]=nod_pt;
853 existing_node_pt[node_number-1]=nod_pt;
858 nod_pt=el_pt->construct_boundary_node(oomph_lib_node_number[j]);
859 Node_pt[node_number-1]=nod_pt;
860 existing_node_pt[node_number-1]=nod_pt;
863 for (std::set<unsigned>::iterator it=
864 one_based_boundaries_of_node[node_number].begin();
865 it!=one_based_boundaries_of_node[node_number].end();it++)
867 add_boundary_node((*it)-1,nod_pt);
873 for (
unsigned i=0;
i<3;
i++)
886 unsigned n_region=region_element.size();
887 this->Region_element_pt.resize(n_region);
888 this->Region_attribute.resize(n_region);
889 unsigned region_count=0;
890 for (std::map<
unsigned,std::set<unsigned> >::iterator it=
891 region_element.begin();it!=region_element.end();it++)
893 this->Region_element_pt[region_count].resize((*it).second.size());
894 unsigned one_based_region_id=(*it).first;
895 this->Region_attribute[region_count]=one_based_region_id-1;
897 for (std::set<unsigned>::iterator itt=(*it).second.begin();
898 itt!=(*it).second.end();itt++)
900 unsigned one_based_el_number=(*itt);
901 this->Region_element_pt[region_count][count]=
902 dynamic_cast<FiniteElement*
>(Element_pt[one_based_el_number-1]);
911 bool plot_for_debugging=
false;
912 if (plot_for_debugging)
914 std::ofstream outfile;
920 outfile_name=mesh_file_stem+
"_element_nodes.dat";
921 outfile.open(outfile_name.c_str());
923 element_node_index.begin();it!=element_node_index.end();it++)
925 std::set<unsigned> shite_nodes;
926 unsigned el_id=(*it).first;
927 std::stringstream tmp_out;
929 itt!=(*it).second.end();itt++)
931 unsigned node_number=(*itt);
932 shite_nodes.insert(node_number);
935 for (
unsigned i=0;
i<n;
i++)
937 tmp_out << x[
i] <<
" ";
939 tmp_out << node_number << std::endl;
941 std::string prefix=
", N=4, E=1, F=FEPOINT, ET=TETRAHEDRON";
943 if ((*it).second.size()==3)
945 prefix=
", N=3, E=1, F=FEPOINT, ET=TRIANGLE";
948 outfile <<
"ZONE T=\"one-based element id=" 949 << el_id <<
"\"" << prefix << std::endl;
950 outfile << tmp_out.str();
951 outfile << postfix << std::endl;
957 outfile_name=mesh_file_stem+
"_boundary_nodes.dat";
958 outfile.open(outfile_name.c_str());
959 for (std::map<
unsigned,std::set<unsigned> >::iterator it=
960 boundary_node.begin();it!=boundary_node.end();it++)
962 unsigned one_based_boundary_id=(*it).first;
963 outfile <<
"ZONE T=\"one-based boundary id=" 964 << one_based_boundary_id <<
"\"" << std::endl;
965 for (std::set<unsigned>::iterator itt=(*it).second.begin();
966 itt!=(*it).second.end();itt++)
968 unsigned node_number=(*itt);
971 for (
unsigned i=0;
i<n;
i++)
973 outfile << x[
i] <<
" ";
975 outfile << node_number << std::endl;
983 for (std::map<
unsigned,std::set<unsigned> >::iterator it=
984 element_next_to_boundary.begin();
985 it!=element_next_to_boundary.end();it++)
987 unsigned one_based_boundary_id=(*it).first;
988 outfile_name=mesh_file_stem+
"_elements_next_to_boundary_" 990 outfile.open(outfile_name.c_str());
991 for (std::set<unsigned>::iterator itt=(*it).second.begin();
992 itt!=(*it).second.end();itt++)
994 outfile <<
"ZONE T=\"one-based boundary " 995 << one_based_boundary_id
996 <<
"\", N=4, E=1, F=FEPOINT, ET=TETRAHEDRON" 998 unsigned el_number=(*itt);
999 unsigned nnod=element_node_index[el_number].size();
1000 for (
unsigned j=0;j<nnod;j++)
1002 unsigned node_number=element_node_index[el_number][j];
1004 unsigned n=x.size();
1005 for (
unsigned i=0;
i<n;
i++)
1007 outfile << x[
i] <<
" ";
1009 outfile << std::endl;
1011 outfile <<
"1 2 3 4" << std::endl;
1020 unsigned nel=this->nelement();
1021 for (
unsigned e=0;e<nel;e++)
1023 vol+=this->finite_element_pt(e)->size();
1025 oomph_info <<
"Total volume of all elements in scaffold mesh: " 1026 << vol << std::endl;
1038 Gmsh_parameters_pt->outer_boundary_pt();
1041 Gmsh_parameters_pt->internal_surface_pt();
1046 Gmsh_parameters_pt->target_size_file_name();
1049 std::string filename=Gmsh_parameters_pt->geo_and_msh_file_stem()+
".geo";
1050 std::ofstream geo_file;
1051 geo_file.open(filename.c_str());
1053 geo_file <<
"// Uniform element size" << std::endl;
1054 geo_file <<
"//---------------------" << std::endl;
1055 geo_file <<
"lc=" << pow(element_volume,1.0/3.0) <<
";" << std::endl;
1056 geo_file << std::endl;
1062 geo_file <<
"// Outer box" << std::endl;
1063 geo_file <<
"//==========" << std::endl;
1064 geo_file << std::endl;
1065 geo_file <<
"// Vertices" << std::endl;
1066 geo_file <<
"//---------" << std::endl;
1067 std::map<TetMeshVertex*,unsigned> vertex_number;
1068 unsigned nv=outer_boundary_pt->
nvertex();
1069 for (
unsigned j=0;j<nv;j++)
1072 vertex_number[vertex_pt]=j;
1073 geo_file <<
"Point(" << j+1 <<
")={";
1074 for (
unsigned i=0;
i<3;
i++)
1076 geo_file << vertex_pt->
x(
i) <<
",";
1078 geo_file <<
"lc};" << std::endl;
1083 std::set<TetEdge> tet_edge_set;
1084 unsigned nfacet=outer_boundary_pt->
nfacet();
1085 for (
unsigned f=0;f<nfacet;f++)
1088 unsigned nv=facet_pt->
nvertex();
1089 for (
unsigned j=0;j<nv-1;j++)
1093 TetEdge my_tet_edge(vertex_number[first_vertex_pt]+1,
1094 vertex_number[second_vertex_pt]+1);
1095 tet_edge_set.insert(my_tet_edge);
1099 TetEdge my_tet_edge(vertex_number[first_vertex_pt]+1,
1100 vertex_number[second_vertex_pt]+1);
1101 tet_edge_set.insert(my_tet_edge);
1105 geo_file <<std::endl;
1106 geo_file <<
"// Edge of outer box" << std::endl;
1107 geo_file <<
"//------------------" << std::endl;
1109 std::map<TetEdge,unsigned> tet_edge;
1110 for (std::set<TetEdge>::iterator it=tet_edge_set.begin();
1111 it!=tet_edge_set.end();it++)
1113 tet_edge.insert(std::make_pair((*it),count));
1114 geo_file <<
"Line(" << count+1 <<
")={" 1115 << (*it).first_vertex_id()
1117 << (*it).second_vertex_id()
1118 <<
"};" << std::endl;
1124 geo_file <<std::endl;
1125 geo_file <<
"// Faces of outer box" << std::endl;
1126 geo_file <<
"//-------------------" << std::endl;
1127 for (
unsigned f=0;f<nfacet;f++)
1129 geo_file <<
"Line Loop(" << f+1 <<
")={";
1132 unsigned nv=facet_pt->
nvertex();
1133 for (
unsigned j=0;j<nv-1;j++)
1137 TetEdge my_tet_edge(vertex_number[first_vertex_pt]+1,
1138 vertex_number[second_vertex_pt]+1);
1140 std::map<TetEdge,unsigned>::iterator it=tet_edge.find(my_tet_edge);
1143 geo_file << -int((it->second)+1) <<
",";
1147 geo_file << ((it->second)+1) <<
",";
1155 TetEdge my_tet_edge(vertex_number[first_vertex_pt]+1,
1156 vertex_number[second_vertex_pt]+1);
1158 std::map<TetEdge,unsigned>::iterator it=tet_edge.find(my_tet_edge);
1161 geo_file << -int((it->second)+1) <<
"};" << std::endl;
1165 geo_file << ((it->second)+1) <<
"};" << std::endl;
1167 geo_file <<
"Plane Surface(" << f+1 <<
")={" << f+1 <<
"};" 1173 geo_file << std::endl;
1174 geo_file <<
"// Define Plane Surfaces bounding the volume" << std::endl;
1175 geo_file <<
"//------------------------------------------" << std::endl;
1176 geo_file <<
"Surface Loop(1) = {";
1177 for (
unsigned f=0;f<nfacet-1;f++)
1179 geo_file << f+1 <<
",";
1181 geo_file << nfacet <<
"};" << std::endl;
1184 geo_file << std::endl;
1185 geo_file <<
"// Define one-based boundary IDs" << std::endl;
1186 geo_file <<
"//------------------------------" << std::endl;
1187 for (
unsigned f=0;f<nfacet;f++)
1189 unsigned one_based_boundary_id=
1191 geo_file <<
"Physical Surface(" << one_based_boundary_id
1192 <<
") = {" << f+1 <<
"};" << std::endl;
1200 unsigned nvertex_offset=outer_boundary_pt->
nvertex();
1201 unsigned nfacet_offset=outer_boundary_pt->
nfacet();
1202 unsigned nvolume_offset=1;
1203 unsigned nline_offset=tet_edge.size();
1209 std::map<unsigned,Vector<unsigned> >
1210 surfaces_to_be_embedded_in_specified_one_based_region;
1214 unsigned n_internal=internal_surface_pt.size();
1215 for (
unsigned i_internal=0;i_internal<n_internal;i_internal++)
1221 internal_surface_pt[i_internal]);
1222 bool inner_surface_is_closed=
true;
1223 if (closed_srf_pt==0)
1225 inner_surface_is_closed=
false;
1229 unsigned number_of_volumes_created_for_this_internal_object=0;
1232 geo_file <<std::endl;
1233 geo_file <<std::endl;
1234 geo_file <<
"// Inner faceted surface " << i_internal << std::endl;
1235 geo_file <<
"//==========================" << std::endl;
1236 geo_file << std::endl;
1237 geo_file <<
"// Vertices" << std::endl;
1238 geo_file <<
"//---------" << std::endl;
1239 std::map<TetMeshVertex*,unsigned> vertex_number;
1240 unsigned nv=internal_surface_pt[i_internal]->nvertex();
1241 for (
unsigned j=0;j<nv;j++)
1244 internal_surface_pt[i_internal]->vertex_pt(j);
1245 vertex_number[vertex_pt]=nvertex_offset+j;
1246 geo_file <<
"Point(" << nvertex_offset+j+1 <<
")={";
1247 for (
unsigned i=0;
i<3;
i++)
1249 geo_file << vertex_pt->
x(
i) <<
",";
1251 geo_file <<
"lc};" << std::endl;
1255 std::set<TetEdge> tet_edge_set;
1256 unsigned nfacet=internal_surface_pt[i_internal]->nfacet();
1257 for (
unsigned f=0;f<nfacet;f++)
1259 TetMeshFacet* facet_pt=internal_surface_pt[i_internal]->facet_pt(f);
1260 unsigned nv=facet_pt->
nvertex();
1261 for (
unsigned j=0;j<nv-1;j++)
1265 TetEdge my_tet_edge(vertex_number[first_vertex_pt]+1,
1266 vertex_number[second_vertex_pt]+1);
1267 tet_edge_set.insert(my_tet_edge);
1271 TetEdge my_tet_edge(vertex_number[first_vertex_pt]+1,
1272 vertex_number[second_vertex_pt]+1);
1273 tet_edge_set.insert(my_tet_edge);
1276 geo_file <<std::endl;
1277 geo_file <<
"// Edge of inner faceted surface" << std::endl;
1278 geo_file <<
"//------------------------------" << std::endl;
1280 std::map<TetEdge,unsigned> tet_edge;
1281 for (std::set<TetEdge>::iterator it=tet_edge_set.begin();
1282 it!=tet_edge_set.end();it++)
1284 tet_edge.insert(std::make_pair((*it),nline_offset+count));
1285 geo_file <<
"Line(" << nline_offset+count+1 <<
")={" 1286 << (*it).first_vertex_id()
1288 << (*it).second_vertex_id()
1289 <<
"};" << std::endl;
1295 geo_file <<std::endl;
1296 geo_file <<
"// Faces of inner faceted surface" << std::endl;
1297 geo_file <<
"//-------------------------------" << std::endl;
1298 for (
unsigned f=0;f<nfacet;f++)
1300 geo_file <<
"Line Loop(" << nfacet_offset+f+1 <<
")={";
1302 TetMeshFacet* facet_pt=internal_surface_pt[i_internal]->facet_pt(f);
1303 unsigned nv=facet_pt->
nvertex();
1304 for (
unsigned j=0;j<nv-1;j++)
1308 TetEdge my_tet_edge(vertex_number[first_vertex_pt]+1,
1309 vertex_number[second_vertex_pt]+1);
1311 std::map<TetEdge,unsigned>::iterator it=tet_edge.find(my_tet_edge);
1314 geo_file << -int((it->second)+1) <<
",";
1318 geo_file << ((it->second)+1) <<
",";
1326 TetEdge my_tet_edge(vertex_number[first_vertex_pt]+1,
1327 vertex_number[second_vertex_pt]+1);
1329 std::map<TetEdge,unsigned>::iterator it=tet_edge.find(my_tet_edge);
1332 geo_file << -int((it->second)+1) <<
"};" << std::endl;
1336 geo_file << ((it->second)+1) <<
"};" << std::endl;
1338 geo_file <<
"Plane Surface(" << nfacet_offset+f+1 <<
")={" 1339 << nfacet_offset+f+1
1340 <<
"};" << std::endl;
1344 bool facet_is_embedded_in_a_volume=facet_pt->
1345 facet_is_embedded_in_a_specified_region();
1346 if (facet_is_embedded_in_a_volume)
1348 unsigned one_based_region_id=
1350 if (one_based_region_id==1)
1352 surfaces_to_be_embedded_in_main_volume.push_back(nfacet_offset+f+1);
1356 surfaces_to_be_embedded_in_specified_one_based_region
1357 [one_based_region_id].push_back(nfacet_offset+f+1);
1363 if (!inner_surface_is_closed)
1365 surfaces_to_be_embedded_in_main_volume.push_back(nfacet_offset+f+1);
1371 std::set<unsigned> all_regions_id;
1375 std::map<unsigned,Vector<unsigned> > region_bounding_facet;
1384 for (
unsigned f=0;f<nfacet;f++)
1386 TetMeshFacet* facet_pt=internal_surface_pt[i_internal]->facet_pt(f);
1388 unsigned nr=region_id.size();
1389 if (nr==1) outer_bounding_facet.push_back(nfacet_offset+f+1);
1390 if ((nr==0)&&inner_surface_is_closed)
1395 surfaces_to_be_embedded_in_main_volume.push_back(nfacet_offset+f+1);
1397 for (std::set<unsigned>::iterator it=region_id.begin();
1398 it!=region_id.end();it++)
1400 all_regions_id.insert((*it));
1401 region_bounding_facet[(*it)].push_back(nfacet_offset+f+1);
1406 unsigned n_regions_bounded_by_facets=all_regions_id.size();
1409 if (n_regions_bounded_by_facets==0)
1411 if (inner_surface_is_closed)
1413 std::ostringstream error_message;
1415 <<
"Something fishy going on! " 1416 <<
"Internal faceted surface " 1418 <<
" is closed but does not bound any regions!\n" 1419 <<
"Specify one-based region ID for all facets using\n\n" 1420 <<
" TetMeshFacet::set_one_based_adjacent_region_id(...)\n\n";
1422 OOMPH_CURRENT_FUNCTION,
1423 OOMPH_EXCEPTION_LOCATION);
1430 unsigned offset_for_extra_hole=0;
1431 if (n_regions_bounded_by_facets>1)
1433 geo_file << std::endl;
1435 <<
"// Define Plane Surfaces bounding compound volume" 1437 <<
"//-----------------------------------------------" 1440 <<
"// that will have to be treated as hole in main volume" 1442 <<
"//-----------------------------------------------" 1444 offset_for_extra_hole=1;
1445 geo_file <<
"Surface Loop(" << nvolume_offset+1
1447 unsigned n=outer_bounding_facet.size();
1448 for (
unsigned f=0;f<n-1;f++)
1450 geo_file << outer_bounding_facet[f] <<
",";
1452 geo_file << outer_bounding_facet[n-1] <<
"};" << std::endl;
1455 number_of_volumes_created_for_this_internal_object++;
1459 volume_id_to_be_subtracted_off.push_back(nvolume_offset+1);
1464 region_bounding_facet.begin();it!=region_bounding_facet.end();
1467 geo_file << std::endl;
1468 geo_file <<
"// Define Plane Surfaces bounding the region volume " 1469 << (*it).first << std::endl;
1471 <<
"//----------------------------------------------------" 1473 geo_file <<
"Surface Loop(" 1474 << nvolume_offset+1+offset_for_extra_hole+count
1476 unsigned n=(*it).second.size();
1477 for (
unsigned f=0;f<n-1;f++)
1479 geo_file << ((*it).second)[f] <<
",";
1481 geo_file << ((*it).second)[n-1] <<
"};" << std::endl;
1483 geo_file << std::endl;
1484 geo_file <<
"// Define volume " 1485 << nvolume_offset+1+offset_for_extra_hole+count
1486 <<
" as the volume bounded by Surface Loop " 1487 << nvolume_offset+1+offset_for_extra_hole+count
1490 <<
"//--------------------------------------------------------" 1492 geo_file <<
"Volume(" 1493 << nvolume_offset+1+offset_for_extra_hole+count <<
")={" 1494 << nvolume_offset+1+offset_for_extra_hole+count
1495 <<
"};" << std::endl;
1496 geo_file << std::endl;
1499 number_of_volumes_created_for_this_internal_object++;
1503 bool mesh_the_volume=
true;
1504 if (closed_srf_pt!=0)
1508 mesh_the_volume=
false;
1511 if (mesh_the_volume)
1513 geo_file <<
"// Define one-based region IDs" << std::endl;
1514 geo_file <<
"//----------------------------" << std::endl;
1515 geo_file <<
"Physical Volume(" << (*it).first
1517 << nvolume_offset+1+offset_for_extra_hole+count
1518 <<
"};" << std::endl;
1520 unsigned ns_embedded=
1521 surfaces_to_be_embedded_in_specified_one_based_region
1522 [(*it).first].size();
1525 geo_file <<
"// This region has " << ns_embedded
1526 <<
" embedded surfaces\n";
1527 geo_file <<
"Surface{";
1528 for (
unsigned i=0;
i<ns_embedded-1;
i++)
1530 geo_file << surfaces_to_be_embedded_in_specified_one_based_region
1531 [(*it).first][
i] <<
",";
1533 geo_file << surfaces_to_be_embedded_in_specified_one_based_region
1534 [(*it).first][ns_embedded-1] <<
"}In Volume {" 1535 << nvolume_offset+1+offset_for_extra_hole+count
1536 <<
"};" << std::endl;
1544 geo_file << std::endl;
1545 geo_file <<
"// Define one-based boundary IDs" << std::endl;
1546 geo_file <<
"//------------------------------" << std::endl;
1547 for (
unsigned f=0;f<nfacet;f++)
1549 unsigned one_based_boundary_id=
1550 internal_surface_pt[i_internal]->one_based_facet_boundary_id(f);
1551 geo_file <<
"Physical Surface(" << one_based_boundary_id
1552 <<
") = {" << nfacet_offset+f+1
1553 <<
"};" << std::endl;
1557 nvertex_offset+=internal_surface_pt[i_internal]->nvertex();
1558 nfacet_offset+=internal_surface_pt[i_internal]->nfacet();
1559 nvolume_offset+=number_of_volumes_created_for_this_internal_object;
1560 nline_offset+=tet_edge.size();
1567 geo_file << std::endl;
1568 geo_file <<
"// Define volume 1 as the volume bounded by Surface Loop 1" 1570 geo_file <<
"//--------------------------------------------------------" 1572 unsigned n=volume_id_to_be_subtracted_off.size();
1575 geo_file <<
"// with volume[s]: ";
1576 for (
unsigned i=0;
i<n;
i++)
1578 geo_file << volume_id_to_be_subtracted_off[
i] <<
" ";
1580 geo_file <<
"removed." << std::endl;
1581 geo_file <<
"//--------------------------------------------------------" 1586 geo_file <<
"Volume(1)={1";
1589 for (
unsigned i=0;
i<n;
i++)
1591 geo_file <<
"," << volume_id_to_be_subtracted_off[
i];
1593 geo_file <<
"};" << std::endl;
1594 geo_file << std::endl;
1598 geo_file <<
"// Define one-based region IDs" << std::endl;
1599 geo_file <<
"//----------------------------" << std::endl;
1600 geo_file <<
"Physical Volume(1" 1601 <<
")={1};" << std::endl;
1605 unsigned ns=surfaces_to_be_embedded_in_main_volume.size();
1608 geo_file << std::endl;
1609 geo_file <<
"// Embed Plane Surfaces in main volume (volume 1)" 1611 geo_file <<
"//-----------------------------------------------" 1613 geo_file <<
"Surface{";
1614 for (
unsigned s=0;
s<ns-1;
s++)
1616 geo_file << surfaces_to_be_embedded_in_main_volume[
s] <<
",";
1618 geo_file << surfaces_to_be_embedded_in_main_volume[ns-1]
1619 <<
"} In Volume{1};" << std::endl;
1620 geo_file << std::endl;
1626 if (use_mesh_grading_from_file)
1632 std::ifstream file(target_size_file_name.c_str(),
1638 std::string error_msg(
"Failed to open target volume file: ");
1641 OOMPH_CURRENT_FUNCTION,
1642 OOMPH_EXCEPTION_LOCATION);
1646 geo_file <<
"Field[1]=Structured;" << std::endl;
1647 geo_file <<
"Field[1].FileName=\"" 1648 << target_size_file_name <<
"\";" << std::endl;
1649 geo_file <<
"Field[1].TextFormat=1;" << std::endl;
1650 geo_file <<
"Background Field = 1;" << std::endl;
1656 geo_file << std::endl;
1657 geo_file <<
"Mesh 3;" << std::endl;
1693 template<
class ELEMENT>
1702 Gmsh_parameters_pt(gmsh_parameters_pt)
1704 bool use_mesh_grading_from_file=
false;
1705 build_it(time_stepper_pt,use_mesh_grading_from_file);
1712 const bool& use_mesh_grading_from_file,
1714 Gmsh_parameters_pt(gmsh_parameters_pt)
1716 build_it(time_stepper_pt,use_mesh_grading_from_file);
1724 const bool& use_mesh_grading_from_file)
1727 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
1731 Gmsh_parameters_pt->outer_boundary_pt();
1734 Gmsh_parameters_pt->internal_surface_pt();
1737 Time_stepper_pt=time_stepper_pt;
1745 for (
unsigned f=0;f<n_facet;f++)
1755 std::ostringstream error_message;
1756 error_message <<
"Boundary IDs have to be one-based. Yours is " 1759 OOMPH_CURRENT_FUNCTION,
1760 OOMPH_EXCEPTION_LOCATION);
1771 unsigned n=Internal_surface_pt.size();
1772 for (
unsigned i=0;
i<n;
i++)
1774 unsigned n_facet=Internal_surface_pt[
i]->nfacet();
1775 for (
unsigned f=0;f<n_facet;f++)
1777 unsigned b=Internal_surface_pt[
i]->one_based_facet_boundary_id(f);
1780 Tet_mesh_faceted_surface_pt[b-1]=Internal_surface_pt[
i];
1781 Tet_mesh_facet_pt[b-1]=
1782 Internal_surface_pt[
i]->facet_pt(f);
1786 std::ostringstream error_message;
1787 error_message <<
"Boundary IDs have to be one-based. Yours is " 1790 OOMPH_CURRENT_FUNCTION,
1791 OOMPH_EXCEPTION_LOCATION);
1800 use_mesh_grading_from_file);
1803 build_from_scaffold(tmp_scaffold_mesh_pt,time_stepper_pt);
1806 delete tmp_scaffold_mesh_pt;
1807 tmp_scaffold_mesh_pt=0;
1810 unsigned nb=nboundary();
1811 for (
unsigned b=0;b<nb;b++)
1813 bool switch_normal=
false;
1814 setup_boundary_coordinates<ELEMENT>(b,switch_normal);
1819 snap_nodes_onto_geometric_objects();
1837 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(3);
1840 unsigned nelem=tmp_scaffold_mesh_pt->
nelement();
1841 Element_pt.resize(nelem);
1844 std::map<FiniteElement*,unsigned> scaffold_mesh_element_number;
1847 unsigned nnode_scaffold=tmp_scaffold_mesh_pt->
nnode();
1848 Node_pt.resize(nnode_scaffold);
1851 unsigned nbound=tmp_scaffold_mesh_pt->
nboundary();
1852 set_nboundary(nbound);
1855 Boundary_element_pt.resize(nbound);
1856 Face_index_at_boundary.resize(nbound);
1857 Boundary_region_element_pt.resize(nbound);
1858 Face_index_region_at_boundary.resize(nbound);
1861 for (
unsigned e=0;
e<nelem;
e++)
1863 Element_pt[
e]=
new ELEMENT;
1872 std::map<Node*,unsigned> global_number;
1873 unsigned global_count=0;
1876 for (
unsigned e=0;
e<nelem;
e++)
1883 for (
unsigned j=0;j<nnod_el;j++)
1887 Node* scaffold_node_pt=
1892 unsigned j_global=global_number[scaffold_node_pt];
1899 std::set<unsigned>* boundaries_pt;
1903 if (boundaries_pt!=0)
1906 Node* new_node_pt=finite_element_pt(
e)->
1907 construct_boundary_node(j,time_stepper_pt);
1913 global_number[scaffold_node_pt]=global_count;
1916 for(std::set<unsigned>::iterator it=boundaries_pt->begin();
1917 it!=boundaries_pt->end();++it)
1919 add_boundary_node(*it,new_node_pt);
1926 finite_element_pt(
e)->construct_node(j,time_stepper_pt);
1932 global_number[scaffold_node_pt]=global_count;
1939 Node_pt[global_count-1]=finite_element_pt(
e)->node_pt(j);
1942 Node_pt[global_count-1]->x(0)=scaffold_node_pt->
x(0);
1943 Node_pt[global_count-1]->x(1)=scaffold_node_pt->
x(1);
1944 Node_pt[global_count-1]->x(2)=scaffold_node_pt->
x(2);
1950 finite_element_pt(
e)->node_pt(j)=Node_pt[j_global-1];
1957 for (
unsigned f=0;f<4;f++)
1959 Node* face_node0_pt=0;
1960 Node* face_node1_pt=0;
1961 Node* face_node2_pt=0;
1966 face_node0_pt=fe_pt->
node_pt(1);
1967 face_node1_pt=fe_pt->
node_pt(2);
1968 face_node2_pt=fe_pt->
node_pt(3);
1972 face_node0_pt=fe_pt->
node_pt(0);
1973 face_node1_pt=fe_pt->
node_pt(2);
1974 face_node2_pt=fe_pt->
node_pt(3);
1978 face_node0_pt=fe_pt->
node_pt(0);
1979 face_node1_pt=fe_pt->
node_pt(1);
1980 face_node2_pt=fe_pt->
node_pt(3);
1984 face_node0_pt=fe_pt->
node_pt(0);
1985 face_node1_pt=fe_pt->
node_pt(1);
1986 face_node2_pt=fe_pt->
node_pt(2);
1991 std::ostringstream error_message;
1992 error_message <<
"Wrong face number " << f << std::endl;
1994 OOMPH_CURRENT_FUNCTION,
1995 OOMPH_EXCEPTION_LOCATION);
2001 std::set<unsigned>* bc0_pt;
2005 std::set<unsigned>* bc1_pt;
2009 std::set<unsigned>* bc2_pt;
2013 std::set<unsigned> common_bound_0_and_1;
2014 std::set_intersection(bc0_pt->begin(),bc0_pt->end(),
2015 bc1_pt->begin(),bc1_pt->end(),
2016 std::inserter(common_bound_0_and_1,
2017 common_bound_0_and_1.begin()));
2018 std::set<unsigned> common_bound_0_and_1_and_2;
2019 std::set_intersection
2020 (common_bound_0_and_1.begin(),
2021 common_bound_0_and_1.end(),
2022 bc2_pt->begin(),bc2_pt->end(),
2023 std::inserter(common_bound_0_and_1_and_2,
2024 common_bound_0_and_1_and_2.begin()));
2025 for (std::set<unsigned>::iterator it=
2026 common_bound_0_and_1_and_2.begin();
2027 it!=common_bound_0_and_1_and_2.end();it++)
2029 Boundary_element_pt[(*it)].push_back(fe_pt);
2030 Face_index_at_boundary[(*it)].push_back(f);
2040 Region_attribute.resize(nr);
2041 Region_element_pt.resize(nr);
2042 for (
unsigned i=0;
i<nr;
i++)
2046 Region_element_pt[
i].resize(nel);
2047 for (
unsigned e=0;
e<nel;
e++)
2050 unsigned scaff_el_number=scaffold_mesh_element_number[scaff_el_pt];
2051 Region_element_pt[
i][
e]=
2058 for (
unsigned f=0;f<4;f++)
2060 Node* face_node0_pt=0;
2061 Node* face_node1_pt=0;
2062 Node* face_node2_pt=0;
2067 face_node0_pt=fe_pt->
node_pt(1);
2068 face_node1_pt=fe_pt->
node_pt(2);
2069 face_node2_pt=fe_pt->
node_pt(3);
2073 face_node0_pt=fe_pt->
node_pt(0);
2074 face_node1_pt=fe_pt->
node_pt(2);
2075 face_node2_pt=fe_pt->
node_pt(3);
2079 face_node0_pt=fe_pt->
node_pt(0);
2080 face_node1_pt=fe_pt->
node_pt(1);
2081 face_node2_pt=fe_pt->
node_pt(3);
2085 face_node0_pt=fe_pt->
node_pt(0);
2086 face_node1_pt=fe_pt->
node_pt(1);
2087 face_node2_pt=fe_pt->
node_pt(2);
2091 std::ostringstream error_message;
2092 error_message <<
"Wrong face number " << f << std::endl;
2094 OOMPH_CURRENT_FUNCTION,
2095 OOMPH_EXCEPTION_LOCATION);
2100 std::set<unsigned>* bc0_pt;
2104 std::set<unsigned>* bc1_pt;
2108 std::set<unsigned>* bc2_pt;
2112 std::set<unsigned> common_bound_0_and_1;
2113 std::set_intersection
2114 (bc0_pt->begin(),bc0_pt->end(),
2115 bc1_pt->begin(),bc1_pt->end(),
2116 std::inserter(common_bound_0_and_1,
2117 common_bound_0_and_1.begin()));
2118 std::set<unsigned> common_bound_0_and_1_and_2;
2119 std::set_intersection
2120 (common_bound_0_and_1.begin(),
2121 common_bound_0_and_1.end(),
2122 bc2_pt->begin(),bc2_pt->end(),
2123 std::inserter(common_bound_0_and_1_and_2,
2124 common_bound_0_and_1_and_2.begin()));
2125 for (std::set<unsigned>::iterator it=
2126 common_bound_0_and_1_and_2.begin();
2127 it!=common_bound_0_and_1_and_2.end();it++)
2129 Boundary_region_element_pt[(*it)][Region_attribute[
i]].
2131 Face_index_region_at_boundary[(*it)][Region_attribute[
i]].
2142 Lookup_for_elements_next_boundary_is_setup=
true;
2150 unsigned n_node_1d=finite_element_pt(0)->nnode_1d();
2153 if ((n_node_1d!=2)&&(n_node_1d!=3))
2155 std::ostringstream error_message;
2156 error_message <<
"Mesh generation from gmsh currently only works\n";
2157 error_message <<
"for nnode_1d = 2 or 3. You're trying to use it\n";
2158 error_message <<
"for nnode_1d=" << n_node_1d << std::endl;
2160 OOMPH_CURRENT_FUNCTION,
2161 OOMPH_EXCEPTION_LOCATION);
2168 std::map<std::pair<Node*,Node*>,
Node*> midside_node_pt;
2171 for(
unsigned e=0;
e<nelem;
e++)
2179 for(
unsigned j=0;j<6;++j)
2183 unsigned new_node_number=0;
2184 std::pair<Node*,Node*> edge;
2224 std::ostringstream error_message;
2225 error_message <<
"Wrong edge number " << j << std::endl;
2227 OOMPH_CURRENT_FUNCTION,
2228 OOMPH_EXCEPTION_LOCATION);
2232 edge=std::make_pair(std::min(nod0_pt,nod1_pt),
2233 std::max(nod0_pt,nod1_pt));
2234 Node* existing_node_pt=midside_node_pt[edge];
2235 if (existing_node_pt==0)
2239 std::set<unsigned> common_bound_0_and_1;
2240 std::set<unsigned>* bc0_pt;
2244 std::set<unsigned>* bc1_pt;
2248 std::set_intersection(bc0_pt->begin(),bc0_pt->end(),
2249 bc1_pt->begin(),bc1_pt->end(),
2250 std::inserter(common_bound_0_and_1,
2251 common_bound_0_and_1.begin()));
2255 Node* new_node_pt = 0;
2258 if (common_bound_0_and_1.size()==0)
2260 new_node_pt=el_pt->
construct_node(new_node_number,time_stepper_pt);
2266 (new_node_number,time_stepper_pt);
2267 for (std::set<unsigned>::iterator it=common_bound_0_and_1.begin();
2268 it!=common_bound_0_and_1.end();it++)
2270 this->add_boundary_node((*it),new_node_pt);
2279 for(
unsigned i=0;
i<3;
i++)
2285 midside_node_pt[edge]=new_node_pt;
2288 Node_pt.push_back(new_node_pt);
2293 el_pt->
node_pt(new_node_number)=existing_node_pt;
2313 template<
class ELEMENT>
2324 const bool& use_mesh_grading_from_file,
2328 use_mesh_grading_from_file,
2331 initialise_adaptation_data();
2343 initialise_adaptation_data();
2356 OOMPH_CURRENT_FUNCTION,
2357 OOMPH_EXCEPTION_LOCATION);
2366 OOMPH_CURRENT_FUNCTION,
2367 OOMPH_EXCEPTION_LOCATION);
2380 this->Gmsh_parameters_pt->max_permitted_edge_ratio();
void create_mesh_from_msh_file()
Create mesh from msh file (created internally via disk-based operations)
bool Reversed
Is it reversed? I.e. is the first input vertex stored after the second one?
std::string Stem_for_filename_gmsh_size_transfer
Stem for filename used to doc target element sizes on gmsh grid. No doc if stem is equal to empty str...
std::string & stem_for_filename_gmsh_size_transfer()
Stem for filename used to doc target element sizes on gmsh grid. No doc if stem is equal to empty str...
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) ...
unsigned Gmsh_onscreen_output_counter
Counter for marker that indicates where we are in gmsh on-screen output.
bool faceted_volume_represents_hole_for_gmsh() const
Does closed surface represent hole for gmsh?
int & counter_for_filename_gmsh_size_transfer()
Counter for filename used to doc target element sizes on gmsh grid. No doc if stem is equal to empty ...
bool is_reversed() const
Edge is reversed in the sense that vertex1 actually has a higher id than vertex2 (when specified in t...
void disable_projection()
Disable projection of old solution onto new mesh.
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors. ...
TetMeshFacetedClosedSurface * Outer_boundary_pt
Pointer to outer boundary.
bool projection_is_disabled()
Is projection of old solution onto new mesh disabled?
unsigned nvertex() const
Number of vertices.
Information for documentation of results: Directory and file number to enable output in the form RESL...
unsigned nvertex() const
Number of vertices.
TetMeshVertex * vertex_pt(const unsigned &j) const
Pointer to j-th vertex.
std::string Target_size_file_name
Filename for target volume (for system-call based transfer to gmsh during mesh adaptation) ...
double Max_element_size
Max. element size during refinement.
bool Projection_is_disabled
Is projection of old solution onto new mesh disabled?
GmshTetMesh(GmshParameters *gmsh_parameters_pt, const bool &use_mesh_grading_from_file, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor. If boolean is set to true, the target element sizes are read from file (used during adap...
GmshTetMesh(GmshParameters *gmsh_parameters_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor.
A general Finite Element class.
void enable_projection()
Disable projection of old solution onto new mesh.
Base class for tet meshes (meshes made of 3D tet elements).
unsigned & gmsh_onscreen_output_counter()
Counter for marker that indicates where we are in gmsh on-screen output.
unsigned second_vertex_id() const
Second vertex id.
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.
double Min_element_size
Min. element size during refinement.
double & min_element_size()
Min. element size during refinement.
Vector< Vector< FiniteElement * > > Region_element_pt
Vectors of vectors of elements in each region (note: this just stores them; the region IDs are contai...
std::string Gmsh_onscreen_output_file_name
Output filename for gmsh on-screen output.
void build_from_scaffold(GmshTetScaffoldMesh *tmp_scaffold_mesh_pt, TimeStepper *time_stepper_pt)
Build unstructured tet gmesh mesh based on output from scaffold.
unsigned long nelement() const
Return number of elements in the mesh.
GmshParameters * Gmsh_parameters_pt
Parameters.
unsigned & max_sample_points_for_limited_locate_zeta_during_target_size_transfer()
Target size is transferred onto regular grid (for gmsh) by locate zeta. We try to find the exact poin...
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.
TetMeshFacetedClosedSurface *& outer_boundary_pt()
Outer boundary.
RefineableGmshTetMesh(GmshParameters *gmsh_parameters_pt, const bool &use_mesh_grading_from_file, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor. If boolean is set to true, the target element sizes are read from file (used during adap...
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
std::string & target_size_file_name()
Filename for target volumes (for system-call based transfer to gmsh during mesh adaptation). Default: .gmsh_target_size_for_adaptation.dat.
TetEdge(const unsigned &vertex1, const unsigned &vertex2)
Constructor: Pass two vertices, identified by their indices Edge "direction" is from lower vertex to ...
unsigned one_based_region_that_facet_is_embedded_in()
int Counter_for_filename_gmsh_size_transfer
Counter for filename used to doc target element sizes on gmsh grid. No doc if stem is equal to empty ...
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object. ...
void build_it(TimeStepper *time_stepper_pt, const bool &use_mesh_grading_from_file)
unsigned nboundary() const
Return number of boundaries.
unsigned unrefine_uniformly()
Refine uniformly.
double & element_volume()
Uniform target element volume.
double & dx_for_target_size_transfer()
(Isotropic) grid spacing for target size transfer
double & max_element_size()
Max. element size during refinement.
std::set< unsigned > one_based_adjacent_region_id() const
Return set of (one-based!) region IDs this facet is adjacent to.
unsigned first_vertex_id() const
First vertex id.
GmshParameters(TetMeshFacetedClosedSurface *const &outer_boundary_pt, const std::string &gmsh_command_line_invocation)
Specify outer boundary of domain to be meshed. Other parameters get default values and can be set via...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
double timer()
returns the time in seconds after some point in past
Vector< TetMeshFacetedSurface * > Internal_surface_pt
Internal boundaries.
unsigned nfacet() const
Number of facets.
double Element_volume
Uniform element volume.
unsigned long nnode() const
Return number of nodes in the mesh.
GmshTetScaffoldMesh(GmshParameters *gmsh_parameters_pt, const bool &use_mesh_grading_from_file)
Build mesh, based on specified parameters. If boolean is set to true, the target element sizes are re...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
unsigned Max_sample_points_for_limited_locate_zeta_during_target_size_transfer
Target size is transferred onto regular grid (for gmsh) by locate zeta. We try to find the exact poin...
std::pair< unsigned, unsigned > Vertex_pair
The vertices (sorted by vertex ids)
Class to collate parameters for Gmsh mesh generation.
void write_geo_file(const bool &use_mesh_grading_from_file)
Write geo file for gmsh.
Helper class to keep track of edges in tet mesh generation.
GmshParameters * Gmsh_parameters_pt
Parameters.
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.
std::string & gmsh_onscreen_output_file_name()
Output filename for gmsh on-screen output.
double & max_permitted_edge_ratio()
Max. permitted edge ratio.
void initialise_adaptation_data()
Helper function to initialise data associated with adaptation.
std::string & geo_and_msh_file_stem()
Stem for geo and msh files (input/output to command-line gmsh invocation)
Base class for refineable tet meshes.
Vector< TetMeshFacetedSurface * > & internal_surface_pt()
Internal boundaries.
double Max_permitted_edge_ratio
Max edge ratio before remesh gets triggered.
Vector< double > Region_attribute
Vector of attributes associated with the elements in each region NOTE: double is enforced on us by te...
TetMeshVertex * vertex_pt(const unsigned &j) const
Pointer to j-th vertex (const)
unsigned nnode() const
Return the number of nodes.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
std::string Gmsh_command_line_invocation
Gmsh command line invocation string.
std::string Geo_and_msh_file_stem
Stem for geo and msh files (input/output to command-line gmsh invocation)
double Dx_for_target_size_transfer
(Isotropic) grid spacing for target size transfer
void refine_uniformly(DocInfo &doc_info)
Unrefine uniformly.
std::string & gmsh_command_line_invocation()
String to be issued via system command to activate gmsh.
std::string to_string(T object, unsigned float_precision=8)
Conversion function that should work for anything with operator<< defined (at least all basic types)...