Write geo file for gmsh.
1023 TetMeshFacetedClosedSurface* outer_boundary_pt =
1026 Vector<TetMeshFacetedSurface*> internal_surface_pt =
1037 std::ofstream geo_file;
1040 geo_file <<
"// Uniform element size" << std::endl;
1041 geo_file <<
"//---------------------" << std::endl;
1042 geo_file <<
"lc=" <<
pow(element_volume, 1.0 / 3.0) <<
";" << std::endl;
1043 geo_file << std::endl;
1049 geo_file <<
"// Outer box" << std::endl;
1050 geo_file <<
"//==========" << std::endl;
1051 geo_file << std::endl;
1052 geo_file <<
"// Vertices" << std::endl;
1053 geo_file <<
"//---------" << std::endl;
1054 std::map<TetMeshVertex*, unsigned> vertex_number;
1055 unsigned nv = outer_boundary_pt->nvertex();
1056 for (
unsigned j = 0;
j < nv;
j++)
1058 TetMeshVertex* vertex_pt = outer_boundary_pt->vertex_pt(
j);
1059 vertex_number[vertex_pt] =
j;
1060 geo_file <<
"Point(" <<
j + 1 <<
")={";
1061 for (
unsigned i = 0;
i < 3;
i++)
1063 geo_file << vertex_pt->x(
i) <<
",";
1065 geo_file <<
"lc};" << std::endl;
1070 std::set<TetEdge> tet_edge_set;
1071 unsigned nfacet = outer_boundary_pt->nfacet();
1072 for (
unsigned f = 0;
f < nfacet;
f++)
1074 TetMeshFacet* facet_pt = outer_boundary_pt->facet_pt(
f);
1075 unsigned nv = facet_pt->nvertex();
1076 for (
unsigned j = 0;
j < nv - 1;
j++)
1078 TetMeshVertex* first_vertex_pt = facet_pt->vertex_pt(
j);
1079 TetMeshVertex* second_vertex_pt = facet_pt->vertex_pt(
j + 1);
1080 TetEdge my_tet_edge(vertex_number[first_vertex_pt] + 1,
1081 vertex_number[second_vertex_pt] + 1);
1082 tet_edge_set.insert(my_tet_edge);
1084 TetMeshVertex* first_vertex_pt = facet_pt->vertex_pt(nv - 1);
1085 TetMeshVertex* second_vertex_pt = facet_pt->vertex_pt(0);
1086 TetEdge my_tet_edge(vertex_number[first_vertex_pt] + 1,
1087 vertex_number[second_vertex_pt] + 1);
1088 tet_edge_set.insert(my_tet_edge);
1092 geo_file << std::endl;
1093 geo_file <<
"// Edge of outer box" << std::endl;
1094 geo_file <<
"//------------------" << std::endl;
1096 std::map<TetEdge, unsigned> tet_edge;
1097 for (std::set<TetEdge>::iterator it = tet_edge_set.begin();
1098 it != tet_edge_set.end();
1101 tet_edge.insert(std::make_pair((*it), count));
1102 geo_file <<
"Line(" << count + 1 <<
")={" << (*it).first_vertex_id()
1103 <<
"," << (*it).second_vertex_id() <<
"};" << std::endl;
1109 geo_file << std::endl;
1110 geo_file <<
"// Faces of outer box" << std::endl;
1111 geo_file <<
"//-------------------" << std::endl;
1112 for (
unsigned f = 0;
f < nfacet;
f++)
1114 geo_file <<
"Line Loop(" <<
f + 1 <<
")={";
1116 TetMeshFacet* facet_pt = outer_boundary_pt->facet_pt(
f);
1117 unsigned nv = facet_pt->nvertex();
1118 for (
unsigned j = 0;
j < nv - 1;
j++)
1120 TetMeshVertex* first_vertex_pt = facet_pt->vertex_pt(
j);
1121 TetMeshVertex* second_vertex_pt = facet_pt->vertex_pt(
j + 1);
1122 TetEdge my_tet_edge(vertex_number[first_vertex_pt] + 1,
1123 vertex_number[second_vertex_pt] + 1);
1125 std::map<TetEdge, unsigned>::iterator it = tet_edge.find(my_tet_edge);
1126 if (my_tet_edge.is_reversed())
1128 geo_file << -
int((it->second) + 1) <<
",";
1132 geo_file << ((it->second) + 1) <<
",";
1136 TetMeshVertex* first_vertex_pt = facet_pt->vertex_pt(nv - 1);
1137 TetMeshVertex* second_vertex_pt = facet_pt->vertex_pt(0);
1138 TetEdge my_tet_edge(vertex_number[first_vertex_pt] + 1,
1139 vertex_number[second_vertex_pt] + 1);
1141 std::map<TetEdge, unsigned>::iterator it = tet_edge.find(my_tet_edge);
1142 if (my_tet_edge.is_reversed())
1144 geo_file << -
int((it->second) + 1) <<
"};" << std::endl;
1148 geo_file << ((it->second) + 1) <<
"};" << std::endl;
1150 geo_file <<
"Plane Surface(" <<
f + 1 <<
")={" <<
f + 1 <<
"};"
1155 geo_file << std::endl;
1156 geo_file <<
"// Define Plane Surfaces bounding the volume" << std::endl;
1157 geo_file <<
"//------------------------------------------" << std::endl;
1158 geo_file <<
"Surface Loop(1) = {";
1159 for (
unsigned f = 0;
f < nfacet - 1;
f++)
1161 geo_file <<
f + 1 <<
",";
1163 geo_file << nfacet <<
"};" << std::endl;
1166 geo_file << std::endl;
1167 geo_file <<
"// Define one-based boundary IDs" << std::endl;
1168 geo_file <<
"//------------------------------" << std::endl;
1169 for (
unsigned f = 0;
f < nfacet;
f++)
1171 unsigned one_based_boundary_id =
1172 outer_boundary_pt->one_based_facet_boundary_id(
f);
1173 geo_file <<
"Physical Surface(" << one_based_boundary_id <<
") = {"
1174 <<
f + 1 <<
"};" << std::endl;
1179 Vector<unsigned> volume_id_to_be_subtracted_off;
1180 unsigned nvertex_offset = outer_boundary_pt->nvertex();
1181 unsigned nfacet_offset = outer_boundary_pt->nfacet();
1182 unsigned nvolume_offset = 1;
1183 unsigned nline_offset = tet_edge.size();
1188 Vector<unsigned> surfaces_to_be_embedded_in_main_volume;
1189 std::map<unsigned, Vector<unsigned>>
1190 surfaces_to_be_embedded_in_specified_one_based_region;
1194 unsigned n_internal = internal_surface_pt.size();
1195 for (
unsigned i_internal = 0; i_internal < n_internal; i_internal++)
1198 TetMeshFacetedClosedSurface* closed_srf_pt =
1199 dynamic_cast<TetMeshFacetedClosedSurface*
>(
1200 internal_surface_pt[i_internal]);
1201 bool inner_surface_is_closed =
true;
1202 if (closed_srf_pt == 0)
1204 inner_surface_is_closed =
false;
1208 unsigned number_of_volumes_created_for_this_internal_object = 0;
1211 geo_file << std::endl;
1212 geo_file << std::endl;
1213 geo_file <<
"// Inner faceted surface " << i_internal << std::endl;
1214 geo_file <<
"//==========================" << std::endl;
1215 geo_file << std::endl;
1216 geo_file <<
"// Vertices" << std::endl;
1217 geo_file <<
"//---------" << std::endl;
1218 std::map<TetMeshVertex*, unsigned> vertex_number;
1219 unsigned nv = internal_surface_pt[i_internal]->nvertex();
1220 for (
unsigned j = 0;
j < nv;
j++)
1222 TetMeshVertex* vertex_pt =
1223 internal_surface_pt[i_internal]->vertex_pt(
j);
1224 vertex_number[vertex_pt] = nvertex_offset +
j;
1225 geo_file <<
"Point(" << nvertex_offset +
j + 1 <<
")={";
1226 for (
unsigned i = 0;
i < 3;
i++)
1228 geo_file << vertex_pt->x(
i) <<
",";
1230 geo_file <<
"lc};" << std::endl;
1234 std::set<TetEdge> tet_edge_set;
1235 unsigned nfacet = internal_surface_pt[i_internal]->nfacet();
1236 for (
unsigned f = 0;
f < nfacet;
f++)
1238 TetMeshFacet* facet_pt = internal_surface_pt[i_internal]->facet_pt(
f);
1239 unsigned nv = facet_pt->nvertex();
1240 for (
unsigned j = 0;
j < nv - 1;
j++)
1242 TetMeshVertex* first_vertex_pt = facet_pt->vertex_pt(
j);
1243 TetMeshVertex* second_vertex_pt = facet_pt->vertex_pt(
j + 1);
1244 TetEdge my_tet_edge(vertex_number[first_vertex_pt] + 1,
1245 vertex_number[second_vertex_pt] + 1);
1246 tet_edge_set.insert(my_tet_edge);
1248 TetMeshVertex* first_vertex_pt = facet_pt->vertex_pt(nv - 1);
1249 TetMeshVertex* second_vertex_pt = facet_pt->vertex_pt(0);
1250 TetEdge my_tet_edge(vertex_number[first_vertex_pt] + 1,
1251 vertex_number[second_vertex_pt] + 1);
1252 tet_edge_set.insert(my_tet_edge);
1255 geo_file << std::endl;
1256 geo_file <<
"// Edge of inner faceted surface" << std::endl;
1257 geo_file <<
"//------------------------------" << std::endl;
1259 std::map<TetEdge, unsigned> tet_edge;
1260 for (std::set<TetEdge>::iterator it = tet_edge_set.begin();
1261 it != tet_edge_set.end();
1264 tet_edge.insert(std::make_pair((*it), nline_offset + count));
1265 geo_file <<
"Line(" << nline_offset + count + 1 <<
")={"
1266 << (*it).first_vertex_id() <<
"," << (*it).second_vertex_id()
1267 <<
"};" << std::endl;
1273 geo_file << std::endl;
1274 geo_file <<
"// Faces of inner faceted surface" << std::endl;
1275 geo_file <<
"//-------------------------------" << std::endl;
1276 for (
unsigned f = 0;
f < nfacet;
f++)
1278 geo_file <<
"Line Loop(" << nfacet_offset +
f + 1 <<
")={";
1280 TetMeshFacet* facet_pt = internal_surface_pt[i_internal]->facet_pt(
f);
1281 unsigned nv = facet_pt->nvertex();
1282 for (
unsigned j = 0;
j < nv - 1;
j++)
1284 TetMeshVertex* first_vertex_pt = facet_pt->vertex_pt(
j);
1285 TetMeshVertex* second_vertex_pt = facet_pt->vertex_pt(
j + 1);
1286 TetEdge my_tet_edge(vertex_number[first_vertex_pt] + 1,
1287 vertex_number[second_vertex_pt] + 1);
1289 std::map<TetEdge, unsigned>::iterator it =
1290 tet_edge.find(my_tet_edge);
1291 if (my_tet_edge.is_reversed())
1293 geo_file << -
int((it->second) + 1) <<
",";
1297 geo_file << ((it->second) + 1) <<
",";
1301 TetMeshVertex* first_vertex_pt = facet_pt->vertex_pt(nv - 1);
1302 TetMeshVertex* second_vertex_pt = facet_pt->vertex_pt(0);
1303 TetEdge my_tet_edge(vertex_number[first_vertex_pt] + 1,
1304 vertex_number[second_vertex_pt] + 1);
1306 std::map<TetEdge, unsigned>::iterator it = tet_edge.find(my_tet_edge);
1307 if (my_tet_edge.is_reversed())
1309 geo_file << -
int((it->second) + 1) <<
"};" << std::endl;
1313 geo_file << ((it->second) + 1) <<
"};" << std::endl;
1315 geo_file <<
"Plane Surface(" << nfacet_offset +
f + 1 <<
")={"
1316 << nfacet_offset +
f + 1 <<
"};" << std::endl;
1320 bool facet_is_embedded_in_a_volume =
1321 facet_pt->facet_is_embedded_in_a_specified_region();
1322 if (facet_is_embedded_in_a_volume)
1324 unsigned one_based_region_id =
1325 facet_pt->one_based_region_that_facet_is_embedded_in();
1326 if (one_based_region_id == 1)
1328 surfaces_to_be_embedded_in_main_volume.push_back(nfacet_offset +
1333 surfaces_to_be_embedded_in_specified_one_based_region
1334 [one_based_region_id]
1335 .push_back(nfacet_offset +
f + 1);
1341 if (!inner_surface_is_closed)
1343 surfaces_to_be_embedded_in_main_volume.push_back(nfacet_offset +
1350 std::set<unsigned> all_regions_id;
1354 std::map<unsigned, Vector<unsigned>> region_bounding_facet;
1359 Vector<unsigned> outer_bounding_facet;
1363 for (
unsigned f = 0;
f < nfacet;
f++)
1365 TetMeshFacet* facet_pt = internal_surface_pt[i_internal]->facet_pt(
f);
1366 std::set<unsigned> region_id(
1367 facet_pt->one_based_adjacent_region_id());
1368 unsigned nr = region_id.size();
1369 if (nr == 1) outer_bounding_facet.push_back(nfacet_offset +
f + 1);
1370 if ((nr == 0) && inner_surface_is_closed)
1374 surfaces_to_be_embedded_in_main_volume.push_back(nfacet_offset +
f +
1377 for (std::set<unsigned>::iterator it = region_id.begin();
1378 it != region_id.end();
1381 all_regions_id.insert((*it));
1382 region_bounding_facet[(*it)].push_back(nfacet_offset +
f + 1);
1387 unsigned n_regions_bounded_by_facets = all_regions_id.size();
1390 if (n_regions_bounded_by_facets == 0)
1392 if (inner_surface_is_closed)
1394 std::ostringstream error_message;
1396 <<
"Something fishy going on! "
1397 <<
"Internal faceted surface " << i_internal
1398 <<
" is closed but does not bound any regions!\n"
1399 <<
"Specify one-based region ID for all facets using\n\n"
1400 <<
" TetMeshFacet::set_one_based_adjacent_region_id(...)\n\n";
1401 throw OomphLibError(error_message.str(),
1410 unsigned offset_for_extra_hole = 0;
1411 if (n_regions_bounded_by_facets > 1)
1413 geo_file << std::endl;
1414 geo_file <<
"// Define Plane Surfaces bounding compound volume"
1416 <<
"//-----------------------------------------------"
1418 geo_file <<
"// that will have to be treated as hole in main volume"
1420 <<
"//-----------------------------------------------"
1422 offset_for_extra_hole = 1;
1423 geo_file <<
"Surface Loop(" << nvolume_offset + 1 <<
") = {";
1424 unsigned n = outer_bounding_facet.size();
1425 for (
unsigned f = 0;
f <
n - 1;
f++)
1427 geo_file << outer_bounding_facet[
f] <<
",";
1429 geo_file << outer_bounding_facet[
n - 1] <<
"};" << std::endl;
1432 number_of_volumes_created_for_this_internal_object++;
1436 volume_id_to_be_subtracted_off.push_back(nvolume_offset + 1);
1440 for (std::map<
unsigned, Vector<unsigned>>::iterator it =
1441 region_bounding_facet.begin();
1442 it != region_bounding_facet.end();
1445 geo_file << std::endl;
1446 geo_file <<
"// Define Plane Surfaces bounding the region volume "
1447 << (*it).first << std::endl;
1448 geo_file <<
"//----------------------------------------------------"
1450 geo_file <<
"Surface Loop("
1451 << nvolume_offset + 1 + offset_for_extra_hole + count
1453 unsigned n = (*it).second.size();
1454 for (
unsigned f = 0;
f <
n - 1;
f++)
1456 geo_file << ((*it).second)[
f] <<
",";
1458 geo_file << ((*it).second)[
n - 1] <<
"};" << std::endl;
1460 geo_file << std::endl;
1461 geo_file <<
"// Define volume "
1462 << nvolume_offset + 1 + offset_for_extra_hole + count
1463 <<
" as the volume bounded by Surface Loop "
1464 << nvolume_offset + 1 + offset_for_extra_hole + count
1467 <<
"//--------------------------------------------------------"
1469 geo_file <<
"Volume("
1470 << nvolume_offset + 1 + offset_for_extra_hole + count
1472 << nvolume_offset + 1 + offset_for_extra_hole + count
1473 <<
"};" << std::endl;
1474 geo_file << std::endl;
1477 number_of_volumes_created_for_this_internal_object++;
1481 bool mesh_the_volume =
true;
1482 if (closed_srf_pt != 0)
1484 if (closed_srf_pt->faceted_volume_represents_hole_for_gmsh())
1486 mesh_the_volume =
false;
1489 if (mesh_the_volume)
1491 geo_file <<
"// Define one-based region IDs" << std::endl;
1492 geo_file <<
"//----------------------------" << std::endl;
1493 geo_file <<
"Physical Volume(" << (*it).first <<
")={"
1494 << nvolume_offset + 1 + offset_for_extra_hole + count
1495 <<
"};" << std::endl;
1497 unsigned ns_embedded =
1498 surfaces_to_be_embedded_in_specified_one_based_region[(*it)
1501 if (ns_embedded > 0)
1503 geo_file <<
"// This region has " << ns_embedded
1504 <<
" embedded surfaces\n";
1505 geo_file <<
"Surface{";
1506 for (
unsigned i = 0;
i < ns_embedded - 1;
i++)
1509 << surfaces_to_be_embedded_in_specified_one_based_region
1514 << surfaces_to_be_embedded_in_specified_one_based_region
1515 [(*it).first][ns_embedded - 1]
1517 << nvolume_offset + 1 + offset_for_extra_hole + count <<
"};"
1526 geo_file << std::endl;
1527 geo_file <<
"// Define one-based boundary IDs" << std::endl;
1528 geo_file <<
"//------------------------------" << std::endl;
1529 for (
unsigned f = 0;
f < nfacet;
f++)
1531 unsigned one_based_boundary_id =
1532 internal_surface_pt[i_internal]->one_based_facet_boundary_id(
f);
1533 geo_file <<
"Physical Surface(" << one_based_boundary_id <<
") = {"
1534 << nfacet_offset +
f + 1 <<
"};" << std::endl;
1538 nvertex_offset += internal_surface_pt[i_internal]->nvertex();
1539 nfacet_offset += internal_surface_pt[i_internal]->nfacet();
1540 nvolume_offset += number_of_volumes_created_for_this_internal_object;
1541 nline_offset += tet_edge.size();
1547 geo_file << std::endl;
1548 geo_file <<
"// Define volume 1 as the volume bounded by Surface Loop 1"
1550 geo_file <<
"//--------------------------------------------------------"
1552 unsigned n = volume_id_to_be_subtracted_off.size();
1555 geo_file <<
"// with volume[s]: ";
1556 for (
unsigned i = 0;
i <
n;
i++)
1558 geo_file << volume_id_to_be_subtracted_off[
i] <<
" ";
1560 geo_file <<
"removed." << std::endl;
1561 geo_file <<
"//--------------------------------------------------------"
1566 geo_file <<
"Volume(1)={1";
1569 for (
unsigned i = 0;
i <
n;
i++)
1571 geo_file <<
"," << volume_id_to_be_subtracted_off[
i];
1573 geo_file <<
"};" << std::endl;
1574 geo_file << std::endl;
1577 geo_file <<
"// Define one-based region IDs" << std::endl;
1578 geo_file <<
"//----------------------------" << std::endl;
1579 geo_file <<
"Physical Volume(1"
1580 <<
")={1};" << std::endl;
1584 unsigned ns = surfaces_to_be_embedded_in_main_volume.size();
1587 geo_file << std::endl;
1588 geo_file <<
"// Embed Plane Surfaces in main volume (volume 1)"
1590 geo_file <<
"//-----------------------------------------------"
1592 geo_file <<
"Surface{";
1593 for (
unsigned s = 0;
s < ns - 1;
s++)
1595 geo_file << surfaces_to_be_embedded_in_main_volume[
s] <<
",";
1597 geo_file << surfaces_to_be_embedded_in_main_volume[ns - 1]
1598 <<
"} In Volume{1};" << std::endl;
1599 geo_file << std::endl;
1605 if (use_mesh_grading_from_file)
1610 std::ifstream file(target_size_file_name.c_str(), std::ios_base::in);
1613 if (!file.is_open())
1615 std::string error_msg(
"Failed to open target volume file: ");
1616 error_msg +=
"\"" + target_size_file_name;
1617 throw OomphLibError(
1622 geo_file <<
"Field[1]=Structured;" << std::endl;
1623 geo_file <<
"Field[1].FileName=\"" << target_size_file_name <<
"\";"
1625 geo_file <<
"Field[1].TextFormat=1;" << std::endl;
1626 geo_file <<
"Background Field = 1;" << std::endl;
1631 geo_file << std::endl;
1632 geo_file <<
"Mesh 3;" << std::endl;
Vector< TetMeshFacetedSurface * > & internal_surface_pt()
Internal boundaries.
Definition: gmsh_tet_mesh.template.h:83
double & element_volume()
Uniform target element volume.
Definition: gmsh_tet_mesh.template.h:89
std::string & target_size_file_name()
Definition: gmsh_tet_mesh.template.h:97
TetMeshFacetedClosedSurface *& outer_boundary_pt()
Outer boundary.
Definition: gmsh_tet_mesh.template.h:77
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
string filename
Definition: MergeRestartFiles.py:39