27#ifndef OOMPH_GMSH_TET_MESH_HEADER
28#define OOMPH_GMSH_TET_MESH_HEADER
32#include <oomph-lib-config.h>
40#include "generic/sample_point_parameters.h"
41#include "generic/mesh_as_geometric_object.h"
42#include "generic/projection.h"
284 "Muppet! You can't build an edge from one vertex to the same vertex!",
355 template<
class ELEMENT>
365 template<
class ELEMENT>
375 double t_start = TimingHelpers::timer();
381 << TimingHelpers::timer() -
t_start <<
" sec " << std::endl;
382 t_start = TimingHelpers::timer();
387 std::string gmsh_onscreen_output_file_name =
391 if (gmsh_onscreen_output_file_name !=
"")
393 marker <<
"\n\n====================================================\n"
394 <<
" gmsh invocation: "
397 <<
"====================================================\n\n\n"
410 if (gmsh_onscreen_output_file_name !=
"")
421 << TimingHelpers::timer() -
t_start <<
" sec " << std::endl;
422 t_start = TimingHelpers::timer();
427 oomph_info <<
"Time for creating mesh from msh file: "
428 << TimingHelpers::timer() -
t_start <<
" sec " << std::endl;
462 std::string
error_msg(
"Failed to open mesh file: ");
473 if (
line !=
"$MeshFormat")
476 "First line has to contain the string \"$MeshFormat\"; ");
494 if (
line ==
"$Nodes")
502 for (
unsigned j = 0;
j <
nnod;
j++)
510 std::istringstream
iss(
s);
519 if (
line !=
"$EndNodes")
521 std::string
error_msg(
"Line has to contain the string \"$EndNodes\"; ");
532 if (
line !=
"$MeshFormat")
535 "First line has to contain the string \"$MeshFormat\"; ");
562 if (
line ==
"$Elements")
574 for (
unsigned e = 0;
e <
nel;
e++)
614 std::string
error_msg(
"Can't handle element type: ");
634 for (
unsigned i = 2;
i <
ntags;
i++)
645 std::istringstream
iss(
s);
686 if (
line !=
"$EndElements")
689 "Line has to contain the string \"$EndElements\"; ");
700 if (
line !=
"$MeshFormat")
703 "First line has to contain the string \"$MeshFormat\"; ");
725 unsigned nnod = ((*it).second).
size();
729 for (
unsigned j = 0;
j <
nnod;
j++)
732 std::map<unsigned, std::set<unsigned>>::iterator
itt =
736 for (std::set<unsigned>::iterator
ittt = (
itt->second).begin();
745 for (std::map<unsigned, unsigned>::iterator
itt =
750 if ((*itt).second == 3)
784 unsigned el_nnod = (*it).second.size();
828 for (std::set<unsigned>::iterator
it =
839 for (
unsigned i = 0;
i < 3;
i++)
855 for (std::map<
unsigned, std::set<unsigned>>::iterator
it =
864 for (std::set<unsigned>::iterator
itt = (*it).second.begin();
865 itt != (*it).second.end();
894 unsigned el_id = (*it).first;
897 itt != (*it).second.end();
903 unsigned n = x.size();
904 for (
unsigned i = 0;
i <
n;
i++)
910 std::string
prefix =
", N=4, E=1, F=FEPOINT, ET=TETRAHEDRON";
911 std::string
postfix =
"1 2 3 4";
912 if ((*it).second.size() == 3)
914 prefix =
", N=3, E=1, F=FEPOINT, ET=TRIANGLE";
928 for (std::map<
unsigned, std::set<unsigned>>::iterator
it =
935 <<
"\"" << std::endl;
936 for (std::set<unsigned>::iterator
itt = (*it).second.begin();
937 itt != (*it).second.end();
942 unsigned n = x.size();
943 for (
unsigned i = 0;
i <
n;
i++)
954 for (std::map<
unsigned, std::set<unsigned>>::iterator
it =
964 for (std::set<unsigned>::iterator
itt = (*it).second.begin();
965 itt != (*it).second.end();
969 <<
"\", N=4, E=1, F=FEPOINT, ET=TETRAHEDRON" << std::endl;
972 for (
unsigned j = 0;
j <
nnod;
j++)
976 unsigned n = x.size();
977 for (
unsigned i = 0;
i <
n;
i++)
983 outfile <<
"1 2 3 4" << std::endl;
992 for (
unsigned e = 0;
e <
nel;
e++)
996 oomph_info <<
"Total volume of all elements in scaffold mesh: " <<
vol
1014 std::string& target_size_file_name =
1023 geo_file <<
"// Uniform element size" << std::endl;
1024 geo_file <<
"//---------------------" << std::endl;
1025 geo_file <<
"lc=" <<
pow(element_volume, 1.0 / 3.0) <<
";" << std::endl;
1032 geo_file <<
"// Outer box" << std::endl;
1033 geo_file <<
"//==========" << std::endl;
1035 geo_file <<
"// Vertices" << std::endl;
1036 geo_file <<
"//---------" << std::endl;
1038 unsigned nv = outer_boundary_pt->nvertex();
1039 for (
unsigned j = 0;
j <
nv;
j++)
1044 for (
unsigned i = 0;
i < 3;
i++)
1053 unsigned nfacet = outer_boundary_pt->nfacet();
1058 for (
unsigned j = 0;
j <
nv - 1;
j++)
1074 geo_file <<
"// Edge of outer box" << std::endl;
1075 geo_file <<
"//------------------" << std::endl;
1077 std::map<TetEdge, unsigned>
tet_edge;
1083 geo_file <<
"Line(" <<
count + 1 <<
")={" << (*it).first_vertex_id()
1084 <<
"," << (*it).second_vertex_id() <<
"};" << std::endl;
1090 geo_file <<
"// Faces of outer box" << std::endl;
1091 geo_file <<
"//-------------------" << std::endl;
1094 geo_file <<
"Line Loop(" <<
f + 1 <<
")={";
1098 for (
unsigned j = 0;
j <
nv - 1;
j++)
1128 geo_file << ((
it->second) + 1) <<
"};" << std::endl;
1130 geo_file <<
"Plane Surface(" <<
f + 1 <<
")={" <<
f + 1 <<
"};"
1135 geo_file <<
"// Define Plane Surfaces bounding the volume" << std::endl;
1136 geo_file <<
"//------------------------------------------" << std::endl;
1138 for (
unsigned f = 0;
f <
nfacet - 1;
f++)
1145 geo_file <<
"// Define one-based boundary IDs" << std::endl;
1146 geo_file <<
"//------------------------------" << std::endl;
1150 outer_boundary_pt->one_based_facet_boundary_id(
f);
1152 <<
f + 1 <<
"};" << std::endl;
1165 std::map<unsigned, Vector<unsigned>>
1170 unsigned n_internal = internal_surface_pt.size();
1190 geo_file <<
"//==========================" << std::endl;
1192 geo_file <<
"// Vertices" << std::endl;
1193 geo_file <<
"//---------" << std::endl;
1195 unsigned nv = internal_surface_pt[
i_internal]->nvertex();
1196 for (
unsigned j = 0;
j <
nv;
j++)
1202 for (
unsigned i = 0;
i < 3;
i++)
1216 for (
unsigned j = 0;
j <
nv - 1;
j++)
1232 geo_file <<
"// Edge of inner faceted surface" << std::endl;
1233 geo_file <<
"//------------------------------" << std::endl;
1235 std::map<TetEdge, unsigned>
tet_edge;
1242 << (*it).first_vertex_id() <<
"," << (*it).second_vertex_id()
1243 <<
"};" << std::endl;
1249 geo_file <<
"// Faces of inner faceted surface" << std::endl;
1250 geo_file <<
"//-------------------------------" << std::endl;
1257 for (
unsigned j = 0;
j <
nv - 1;
j++)
1264 std::map<TetEdge, unsigned>::iterator
it =
1288 geo_file << ((
it->second) + 1) <<
"};" << std::endl;
1296 facet_pt->facet_is_embedded_in_a_specified_region();
1300 facet_pt->one_based_region_that_facet_is_embedded_in();
1342 facet_pt->one_based_adjacent_region_id());
1352 for (std::set<unsigned>::iterator
it =
region_id.begin();
1371 <<
"Something fishy going on! "
1373 <<
" is closed but does not bound any regions!\n"
1374 <<
"Specify one-based region ID for all facets using\n\n"
1375 <<
" TetMeshFacet::set_one_based_adjacent_region_id(...)\n\n";
1389 geo_file <<
"// Define Plane Surfaces bounding compound volume"
1391 <<
"//-----------------------------------------------"
1393 geo_file <<
"// that will have to be treated as hole in main volume"
1395 <<
"//-----------------------------------------------"
1400 for (
unsigned f = 0;
f <
n - 1;
f++)
1421 geo_file <<
"// Define Plane Surfaces bounding the region volume "
1422 << (*it).first << std::endl;
1423 geo_file <<
"//----------------------------------------------------"
1428 unsigned n = (*it).second.size();
1429 for (
unsigned f = 0;
f <
n - 1;
f++)
1433 geo_file << ((*it).second)[
n - 1] <<
"};" << std::endl;
1438 <<
" as the volume bounded by Surface Loop "
1442 <<
"//--------------------------------------------------------"
1448 <<
"};" << std::endl;
1458 if (
closed_srf_pt->faceted_volume_represents_hole_for_gmsh())
1465 geo_file <<
"// Define one-based region IDs" << std::endl;
1466 geo_file <<
"//----------------------------" << std::endl;
1467 geo_file <<
"Physical Volume(" << (*it).first <<
")={"
1469 <<
"};" << std::endl;
1478 <<
" embedded surfaces\n";
1501 geo_file <<
"// Define one-based boundary IDs" << std::endl;
1502 geo_file <<
"//------------------------------" << std::endl;
1506 internal_surface_pt[
i_internal]->one_based_facet_boundary_id(
f);
1521 geo_file <<
"// Define volume 1 as the volume bounded by Surface Loop 1"
1523 geo_file <<
"//--------------------------------------------------------"
1529 for (
unsigned i = 0;
i <
n;
i++)
1533 geo_file <<
"removed." << std::endl;
1534 geo_file <<
"//--------------------------------------------------------"
1542 for (
unsigned i = 0;
i <
n;
i++)
1549 geo_file <<
"// Define one-based region IDs" << std::endl;
1550 geo_file <<
"//----------------------------" << std::endl;
1552 <<
")={1};" << std::endl;
1559 geo_file <<
"// Embed Plane Surfaces in main volume (volume 1)"
1561 geo_file <<
"//-----------------------------------------------"
1564 for (
unsigned s = 0;
s <
ns - 1;
s++)
1569 <<
"} In Volume{1};" << std::endl;
1580 std::ifstream
file(target_size_file_name.c_str(), std::ios_base::in);
1583 if (!
file.is_open())
1585 std::string
error_msg(
"Failed to open target volume file: ");
1586 error_msg +=
"\"" + target_size_file_name;
1592 geo_file <<
"Field[1]=Structured;" << std::endl;
1593 geo_file <<
"Field[1].FileName=\"" << target_size_file_name <<
"\";"
1595 geo_file <<
"Field[1].TextFormat=1;" << std::endl;
1596 geo_file <<
"Background Field = 1;" << std::endl;
1602 geo_file <<
"Mesh 3;" << std::endl;
1627 template<
class ELEMENT>
1657 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
1670 Outer_boundary_pt = outer_boundary_pt;
1674 unsigned n_facet = Outer_boundary_pt->nfacet();
1677 unsigned b = Outer_boundary_pt->one_based_facet_boundary_id(
f);
1686 error_message <<
"Boundary IDs have to be one-based. Yours is " <<
b
1696 Internal_surface_pt = internal_surface_pt;
1700 unsigned n = Internal_surface_pt.size();
1701 for (
unsigned i = 0;
i <
n;
i++)
1703 unsigned n_facet = Internal_surface_pt[
i]->nfacet();
1706 unsigned b = Internal_surface_pt[
i]->one_based_facet_boundary_id(
f);
1715 error_message <<
"Boundary IDs have to be one-based. Yours is "
1738 for (
unsigned b = 0;
b <
nb;
b++)
1759 MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(3);
1783 for (
unsigned e = 0;
e <
nelem;
e++)
1798 for (
unsigned e = 0;
e <
nelem;
e++)
1878 for (
unsigned f = 0;
f < 4;
f++)
1921 std::set<unsigned>*
bc0_pt;
1925 std::set<unsigned>*
bc1_pt;
1929 std::set<unsigned>*
bc2_pt;
1934 std::set_intersection(
1942 std::set_intersection(
1949 for (std::set<unsigned>::iterator
it =
1967 for (
unsigned i = 0;
i <
nr;
i++)
1972 for (
unsigned e = 0;
e <
nel;
e++)
1982 for (
unsigned f = 0;
f < 4;
f++)
2024 std::set<unsigned>*
bc0_pt;
2028 std::set<unsigned>*
bc1_pt;
2032 std::set<unsigned>*
bc2_pt;
2037 std::set_intersection(
2045 std::set_intersection(
2052 for (std::set<unsigned>::iterator
it =
2083 error_message <<
"Mesh generation from gmsh currently only works\n";
2084 error_message <<
"for nnode_1d = 2 or 3. You're trying to use it\n";
2098 for (
unsigned e = 0;
e <
nelem;
e++)
2106 for (
unsigned j = 0;
j < 6; ++
j)
2111 std::pair<Node*, Node*>
edge;
2167 std::set<unsigned>*
bc0_pt;
2171 std::set<unsigned>*
bc1_pt;
2175 std::set_intersection(
2198 for (std::set<unsigned>::iterator
it =
2212 for (
unsigned i = 0;
i < 3;
i++)
2241 template<
class ELEMENT>
2243 public virtual RefineableTetMeshBase
2278 std::string
error_msg(
"Not written yet...");
2287 std::string
error_msg(
"Not written yet...");
2299 this->Max_permitted_edge_ratio =
Class to collate parameters for Gmsh mesh generation.
Vector< TetMeshFacetedSurface * > & internal_surface_pt()
Internal boundaries.
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...
double Dx_for_target_size_transfer
(Isotropic) grid spacing for target size transfer
double & element_volume()
Uniform target element volume.
TetMeshFacetedClosedSurface * Outer_boundary_pt
Pointer to outer boundary.
unsigned & gmsh_onscreen_output_counter()
Counter for marker that indicates where we are in gmsh on-screen output.
std::string & geo_and_msh_file_stem()
Stem for geo and msh files (input/output to command-line gmsh invocation)
std::string Geo_and_msh_file_stem
Stem for geo and msh files (input/output to command-line gmsh invocation)
std::string & gmsh_onscreen_output_file_name()
Output filename for gmsh on-screen output.
std::string Gmsh_command_line_invocation
Gmsh command line invocation string.
double & max_permitted_edge_ratio()
Max. permitted edge ratio.
double Max_element_size
Max. element size during refinement.
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...
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::string & target_size_file_name()
Filename for target volumes (for system-call based transfer to gmsh during mesh adaptation)....
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 ...
double Min_element_size
Min. element size during refinement.
std::string & gmsh_command_line_invocation()
String to be issued via system command to activate gmsh.
TetMeshFacetedClosedSurface *& outer_boundary_pt()
Outer boundary.
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...
double & max_element_size()
Max. element size during refinement.
double Element_volume
Uniform element volume.
Vector< TetMeshFacetedSurface * > Internal_surface_pt
Internal boundaries.
unsigned Gmsh_onscreen_output_counter
Counter for marker that indicates where we are in gmsh on-screen output.
double & dx_for_target_size_transfer()
(Isotropic) grid spacing for target size transfer
double Max_permitted_edge_ratio
Max edge ratio before remesh gets triggered.
bool projection_is_disabled()
Is projection of old solution onto new mesh disabled?
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...
void disable_projection()
Disable projection of old solution onto new mesh.
std::string Target_size_file_name
Filename for target volume (for system-call based transfer to gmsh during mesh adaptation)
double & min_element_size()
Min. element size during refinement.
bool Projection_is_disabled
Is projection of old solution onto new mesh disabled?
std::string Gmsh_onscreen_output_file_name
Output filename for gmsh on-screen output.
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 ...
void enable_projection()
Disable projection of old solution onto new mesh.
GmshTetMesh(GmshParameters *gmsh_parameters_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor.
GmshParameters * Gmsh_parameters_pt
Parameters.
void build_from_scaffold(GmshTetScaffoldMesh *tmp_scaffold_mesh_pt, TimeStepper *time_stepper_pt)
Build unstructured tet gmesh mesh based on output from scaffold.
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...
void build_it(TimeStepper *time_stepper_pt, const bool &use_mesh_grading_from_file)
void create_mesh_from_msh_file()
Create mesh from msh file (created internally via disk-based operations)
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...
void write_geo_file(const bool &use_mesh_grading_from_file)
Write geo file for gmsh.
GmshParameters * Gmsh_parameters_pt
Parameters.
Collapsible channel mesh with MacroElement-based node update. The collapsible segment is represented ...
void refine_uniformly(DocInfo &doc_info)
Unrefine uniformly.
unsigned unrefine_uniformly()
Refine uniformly.
RefineableGmshTetMesh(GmshParameters *gmsh_parameters_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor.
void adapt(const Vector< double > &elem_error)
Adapt mesh, based on elemental error provided.
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...
void initialise_adaptation_data()
Helper function to initialise data associated with adaptation.
Helper class to keep track of edges in tet mesh generation.
bool operator==(const TetEdge &tet_edge) const
Comparison operator: Edges are identical if their sorted (and therefore possibly reversed) vertex ids...
std::pair< unsigned, unsigned > Vertex_pair
The vertices (sorted by vertex ids)
unsigned second_vertex_id() const
Second vertex id.
bool is_reversed() const
Edge is reversed in the sense that vertex1 actually has a higher id than vertex2 (when specified in t...
TetEdge(const unsigned &vertex1, const unsigned &vertex2)
Constructor: Pass two vertices, identified by their indices Edge "direction" is from lower vertex to ...
bool operator<(const TetEdge &tet_edge) const
Comparison operator. Lexicographic comparison based on vertex ids.
unsigned first_vertex_id() const
First vertex id.
bool Reversed
Is it reversed? I.e. is the first input vertex stored after the second one?