[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Getfem-commits] (no subject)
From: |
Konstantinos Poulios |
Subject: |
[Getfem-commits] (no subject) |
Date: |
Wed, 2 Aug 2023 17:14:54 -0400 (EDT) |
branch: cleanup-mesh-import
commit 69884dd486e8e68d7bcdb502f2843c5131c5a91e
Author: Konstantinos Poulios <logari81@gmail.com>
AuthorDate: Wed Aug 2 23:14:40 2023 +0200
Change default treatment of overlapping nodes and cleanup of mesh import
---
src/getfem/getfem_import.h | 62 ++++---
src/getfem_import.cc | 439 ++++++++++++++++++++++-----------------------
2 files changed, 248 insertions(+), 253 deletions(-)
diff --git a/src/getfem/getfem_import.h b/src/getfem/getfem_import.h
index 10210207..cad32fd0 100644
--- a/src/getfem/getfem_import.h
+++ b/src/getfem/getfem_import.h
@@ -76,9 +76,9 @@ namespace getfem {
parametrization of the mesh in Gmsh .geo file must assign a
different number to each region, the problem exists because in
Gmsh can coexist, for example, "Physical Surface (200)" and
- "Physical Line (200)", as they are different "types of regions"
- in Gmsh, that which does not occur in GetFEM since there is
- only one "type of region".
+ "Physical Line (200)", as they are different types of regions
+ in Gmsh, which cannot occur in GetFEM since there is only one
+ type of region.
- "cdb" for meshes generated by ANSYS (in blocked format).
@@ -103,11 +103,19 @@ namespace getfem {
- "am_fmt" for 2D meshes from emc2
[http://pauillac.inria.fr/cdrom/prog/unix/emc2/eng.htm]
+
+ For all mesh formats, overlapping nodes are preserved by default.
+ In order to merge overlapping nodes during the import, add
+ ":merge_overlapping_nodes" to the format specifier.
+ For example:
+ "gmsh:merge_overlapping_nodes"
+ "cdb:merge_overlapping_nodes"
+ "cdb:3:merge_overlapping_nodes"
*/
void import_mesh(const std::string& filename, const std::string& format,
- mesh& m);
+ mesh& m);
void import_mesh(std::istream& f, const std::string& format,
- mesh& m);
+ mesh& m);
void import_mesh(const std::string& filename, mesh& m);
/** Import a mesh file in format generated by Gmsh.
@@ -140,38 +148,42 @@ namespace getfem {
be tested.
*/
void import_mesh_gmsh(const std::string& filename, mesh& m,
- std::map<std::string, size_type> ®ion_map,
+ bool add_all_element_type = false,
+ std::set<size_type> *lower_dim_convex_rg = nullptr,
+ std::map<std::string, size_type> *region_map = nullptr,
bool remove_last_dimension = true,
- std::map<size_type, std::set<size_type>> *nodal_map =
NULL,
- bool remove_duplicated_nodes = true);
-
- void import_mesh_gmsh(std::istream& f, mesh& m,
+ std::map<size_type, std::set<size_type>> *nodal_map =
nullptr,
+ bool merge_overlapping_nodes = false);
+ void import_mesh_gmsh(const std::string& filename, mesh& m,
std::map<std::string, size_type> ®ion_map,
bool remove_last_dimension = true,
- std::map<size_type, std::set<size_type>> *nodal_map =
NULL,
- bool remove_duplicated_nodes = true);
-
- void import_mesh_gmsh(const std::string& filename, mesh& m,
+ std::map<size_type, std::set<size_type>> *nodal_map =
nullptr,
+ bool merge_overlapping_nodes = false) {
+ import_mesh_gmsh(filename, m, false, nullptr, ®ion_map,
+ remove_last_dimension, nodal_map,
merge_overlapping_nodes);
+ }
+ void import_mesh_gmsh(std::istream& f, mesh& m,
bool add_all_element_type = false,
- std::set<size_type> *lower_dim_convex_rg = NULL,
- std::map<std::string, size_type> *region_map = NULL,
+ std::set<size_type> *lower_dim_convex_rg = nullptr,
+ std::map<std::string, size_type> *region_map = nullptr,
bool remove_last_dimension = true,
- std::map<size_type, std::set<size_type>> *nodal_map =
NULL,
- bool remove_duplicated_nodes = true);
-
+ std::map<size_type, std::set<size_type>> *nodal_map =
nullptr,
+ bool merge_overlapping_nodes = false);
void import_mesh_gmsh(std::istream& f, mesh& m,
- bool add_all_element_type = false,
- std::set<size_type> *lower_dim_convex_rg = NULL,
- std::map<std::string, size_type> *region_map = NULL,
+ std::map<std::string, size_type> ®ion_map,
bool remove_last_dimension = true,
- std::map<size_type, std::set<size_type>> *nodal_map =
NULL,
- bool remove_duplicated_nodes = true);
+ std::map<size_type, std::set<size_type>> *nodal_map =
nullptr,
+ bool merge_overlapping_nodes = false) {
+ import_gmsh_mesh(f, m, false, nullptr, ®ion_map,
+ remove_last_dimension, nodal_map,
merge_overlapping_nodes);
+ }
/** for gmsh and gid meshes, the mesh nodes are always 3D, so for a 2D mesh
the z-component of nodes should be removed */
void maybe_remove_last_dimension(mesh &msh);
/** for gmsh meshes, create table linking region name to region_id. */
- std::map<std::string, size_type>
read_region_names_from_gmsh_mesh_file(std::istream& f);
+ std::map<std::string, size_type>
+ read_region_names_from_gmsh_mesh_file(std::istream& f);
}
#endif /* GETFEM_IMPORT_H__ */
diff --git a/src/getfem_import.cc b/src/getfem_import.cc
index 7056697c..13cf1414 100644
--- a/src/getfem_import.cc
+++ b/src/getfem_import.cc
@@ -1,6 +1,7 @@
/*===========================================================================
- Copyright (C) 2000-2020 Julien Pommier
+ Copyright (C) 2000-2023 Julien Pommier
+ 2012-2023 Konstantinos Poulios
This file is a part of GetFEM
@@ -29,6 +30,58 @@
namespace getfem {
+ // Main mesh import function, dispatches between native GetFEM mesh
+ // file format and all other formats
+ void import_mesh(const std::string& filename, mesh& m) {
+ size_type pos = filename.find_last_of(":");
+ if (pos != std::string::npos)
+ getfem::import_mesh(filename.substr(pos+1), filename.substr(0,pos), m);
+ else
+ m.read_from_file(filename);
+ }
+
+ // Deals with all other options than native GetFEM mesh file format
+ // Dispatches between structured meshes to be generated by GetFEM
+ // and all supported file formats
+ void import_mesh(const std::string& filename, const std::string& format,
+ mesh& m) {
+ m.clear();
+ try {
+ if (bgeot::casecmp(format,"structured")==0)
+ regular_mesh(m, filename);
+ else if (bgeot::casecmp(format,"structured_ball")==0)
+ regular_ball_mesh(m, filename);
+ else if (bgeot::casecmp(format,"structured_ball_shell")==0)
+ regular_ball_shell_mesh(m, filename);
+ else {
+ std::ifstream f(filename.c_str());
+ GMM_ASSERT1(f.good(), "can't open file " << filename);
+ /* throw exceptions when an error occurs */
+ f.exceptions(std::ifstream::badbit | std::ifstream::failbit);
+ import_mesh(f, format, m); // main dispatcher between all supported
+ f.close(); // file formats is in this function
+ }
+ }
+ catch (std::logic_error& exc) {
+ m.clear();
+ throw exc;
+ }
+ catch (std::ios_base::failure& exc) {
+ m.clear();
+ GMM_ASSERT1(false, "error while importing " << format
+ << " mesh file \"" << filename << "\" : " << exc.what());
+ }
+ catch (std::runtime_error& exc) {
+ m.clear();
+ throw exc;
+ }
+ }
+
+
+
+ // Specific mesh file format implementations
+
+
/* mesh file from gmsh [http://www.geuz.org/gmsh/]*/
struct gmsh_cv_info {
@@ -176,8 +229,8 @@ namespace getfem {
}
};
- std::map<std::string, size_type>
read_region_names_from_gmsh_mesh_file(std::istream& f)
- {
+ std::map<std::string, size_type>
+ read_region_names_from_gmsh_mesh_file(std::istream& f) {
std::map<std::string, size_type> region_map;
bgeot::read_until(f, "$PhysicalNames");
size_type nb_regions;
@@ -200,6 +253,22 @@ namespace getfem {
return region_map;
}
+ void maybe_remove_last_dimension(mesh &m) {
+ unsigned N = m.dim();
+ if (N >= 1) {
+ bool is_flat = true;
+ for (const base_node &pt : m.points())
+ if (pt[N-1] != 0)
+ is_flat = false;
+ if (is_flat) {
+ base_matrix M(N-1,N);
+ for (unsigned i=0; i < N-1; ++i)
+ M(i,i) = 1;
+ m.transformation(M);
+ }
+ }
+ }
+
/*
Format version 1 [for gmsh version < 2.0].
structure: $NOD list_of_nodes $ENDNOD $ELT list_of_elt $ENDELT
@@ -220,31 +289,18 @@ namespace getfem {
for gmsh and gid meshes, the mesh nodes are always 3D, so for a 2D mesh
if remove_last_dimension == true the z-component of nodes will be removed
*/
- static void import_gmsh_mesh_file
- (std::istream& f, mesh& m, int deprecate=0,
- std::map<std::string, size_type> *region_map=NULL,
- std::set<size_type> *lower_dim_convex_rg=NULL,
- bool add_all_element_type = false,
- bool remove_last_dimension = true,
- std::map<size_type, std::set<size_type>> *nodal_map = NULL,
- bool remove_duplicated_nodes = true) {
+ static void import_gmsh_mesh(std::istream& f, mesh& m,
+ bool add_all_element_type,
+ std::set<size_type> *lower_dim_convex_rg,
+ std::map<std::string, size_type> *region_map,
+ bool remove_last_dimension,
+ std::map<size_type, std::set<size_type>>
*nodal_map,
+ bool merge_overlapping_nodes)
+ {
gmm::stream_standard_locale sl(f);
// /* print general warning */
// GMM_WARNING3(" All regions must have different number!");
- /* print deprecate warning */
- if (deprecate!=0){
- GMM_WARNING4("" << endl
- << " deprecate: " << endl
- << " static void" << endl
- << " import_gmsh_mesh_file(std::istream& f,"
- << " mesh& , int version)" << endl
- << " replace with:" << endl
- << " static void" << endl
- << " import_gmsh_mesh_file(std::istream& f,"
- << " mesh&)");
- }
-
/* read the version */
double version;
std::string header;
@@ -257,7 +313,7 @@ namespace getfem {
GMM_ASSERT1(false, "can't read Gmsh format: " << header);
/* read the region names */
- if (region_map != NULL) {
+ if (region_map != nullptr) {
if (version >= 2.) {
*region_map = read_region_names_from_gmsh_mesh_file(f);
}
@@ -288,18 +344,18 @@ namespace getfem {
inds.resize(nb_node);
if (version >= 4.05) {
- for (size_type node_cnt=0; node_cnt < nb_node; ++node_cnt)
- f >> inds[node_cnt];
+ for (size_type node_cnt=0; node_cnt < nb_node; ++node_cnt)
+ f >> inds[node_cnt];
}
for (size_type node_cnt=0; node_cnt < nb_node; ++node_cnt) {
size_type node_id;
base_node n{0,0,0};
- if (version < 4.05) f >> node_id; else node_id = inds[node_cnt];
+ if (version < 4.05) f >> node_id; else node_id = inds[node_cnt];
- f >> n[0] >> n[1] >> n[2];
+ f >> n[0] >> n[1] >> n[2];
msh_node_2_getfem_node[node_id]
- = m.add_point(n, remove_duplicated_nodes ? 0. : -1.);
+ = m.add_point(n, merge_overlapping_nodes ? 0. : -1.);
}
}
@@ -334,7 +390,8 @@ namespace getfem {
if (reg.is_in(region)) {
GMM_WARNING2("Two regions share the same number, "
"the region numbering is modified");
- while (reg.is_in(region)) region += 5;
+ while (reg.is_in(region))
+ region += 5;
}
reg.add(region);
}
@@ -569,73 +626,101 @@ namespace getfem {
size_type ic = m.add_convex(ci.pgt, ci.nodes.begin());
cvok = true;
m.region(ci.region).add(ic);
-
- //convexes with lower dimensions
- }
- else {
+ } else { //convexes with lower dimensions
//convex that lies within the regions of lower_dim_convex_rg
//is imported explicitly as a convex.
- if (lower_dim_convex_rg != NULL &&
+ if (lower_dim_convex_rg != nullptr &&
lower_dim_convex_rg->find(ci.region) !=
lower_dim_convex_rg->end()
&& !is_node) {
- size_type ic = m.add_convex(ci.pgt, ci.nodes.begin());
- cvok = true; m.region(ci.region).add(ic);
- }
- //find if the convex is part of a face of higher dimension convex
- else{
+ size_type ic = m.add_convex(ci.pgt, ci.nodes.begin());
+ cvok = true;
+ m.region(ci.region).add(ic);
+ } else { //find if the convex is part of a face of higher dimension
convex
bgeot::mesh_structure::ind_cv_ct ct=m.convex_to_point(ci.nodes[0]);
for (bgeot::mesh_structure::ind_cv_ct::const_iterator
- it = ct.begin(); it != ct.end(); ++it) {
- if (m.structure_of_convex(*it)->dim() == ci_dim + 1) {
+ it = ct.begin(); it != ct.end(); ++it)
+ if (m.structure_of_convex(*it)->dim() == ci_dim + 1)
for (short_type face=0;
- face < m.structure_of_convex(*it)->nb_faces(); ++face) {
+ face < m.structure_of_convex(*it)->nb_faces(); ++face)
if (m.is_convex_face_having_points(*it, face,
short_type(ci.nodes.size()),
- ci.nodes.begin())) {
+ ci.nodes.begin()))
+ {
m.region(ci.region).add(*it,face);
cvok = true;
}
- }
- }
- }
- if (is_node && (nodal_map != NULL)) {
- for (auto i : ci.nodes) (*nodal_map)[ci.region].insert(i);
- }
- // if the convex is not part of the face of others
- if (!cvok) {
- if (is_node) {
- if (nodal_map == NULL){
+ if (is_node && (nodal_map != nullptr))
+ for (auto i : ci.nodes)
+ (*nodal_map)[ci.region].insert(i);
+ if (!cvok) { // if the convex is not part of the face of others
+ if (is_node)
+ if (nodal_map == nullptr)
GMM_WARNING2("gmsh import ignored a node id: "
<< ci.id << " region :" << ci.region <<
" point is not added explicitly as an
element.");
- }
- }
else if (add_all_element_type) {
size_type ic = m.add_convex(ci.pgt, ci.nodes.begin());
m.region(ci.region).add(ic);
cvok = true;
- } else {
+ } else
GMM_WARNING2("gmsh import ignored an element of type "
<< bgeot::name_of_geometric_trans(ci.pgt) <<
" as it does not belong to the face of another element");
- }
}
}
}
}
}
- if (remove_last_dimension) maybe_remove_last_dimension(m);
+ if (remove_last_dimension)
+ maybe_remove_last_dimension(m);
+ }
+
+ // Just opens the file with the given filename and passes the ifstream
+ void import_mesh_gmsh(const std::string& filename, mesh& m,
+ bool add_all_element_type,
+ std::set<size_type> *lower_dim_convex_rg,
+ std::map<std::string, size_type> *region_map,
+ bool remove_last_dimension,
+ std::map<size_type, std::set<size_type>> *nodal_map,
+ bool merge_overlapping_nodes)
+ {
+ m.clear();
+ try {
+ std::ifstream f(filename.c_str());
+ GMM_ASSERT1(f.good(), "can't open file " << filename);
+ /* throw exceptions when an error occurs */
+ f.exceptions(std::ifstream::badbit | std::ifstream::failbit);
+ import_gmsh_mesh(f, m, add_all_element_type, lower_dim_convex_rg,
region_map,
+ remove_last_dimension, nodal_map,
merge_overlapping_nodes);
+ f.close();
+ }
+ catch (std::logic_error& exc) {
+ m.clear();
+ throw exc;
+ }
+ catch (std::ios_base::failure& exc) {
+ m.clear();
+ GMM_ASSERT1(false, "error while importing " << "gmsh"
+ << " mesh file \"" << filename << "\" : " << exc.what());
+ }
+ catch (std::runtime_error& exc) {
+ m.clear();
+ throw exc;
+ }
}
+
+
/* mesh file from GiD [http://gid.cimne.upc.es/]
supports linear and quadratic elements (quadrilaterals, use 9(or 27)-noded
elements)
*/
- static void import_gid_mesh_file(std::istream& f, mesh& m) {
+ static void import_gid_mesh(std::istream& f, mesh& m,
+ bool merge_overlapping_nodes=false) {
gmm::stream_standard_locale sl(f);
/* read the node list */
size_type dim;
- enum { LIN,TRI,QUAD,TETR, PRISM, HEX,BADELTYPE } eltype=BADELTYPE;
+ enum { LIN,TRI,QUAD,TETR, PRISM, HEX, BADELTYPE } eltype=BADELTYPE;
size_type nnode = 0;
std::map<size_type, size_type> msh_node_2_getfem_node;
std::vector<size_type> cv_nodes, getfem_cv_nodes;
@@ -691,12 +776,13 @@ namespace getfem {
for (dal::bv_visitor ip(gid_nodes_used); !ip.finished(); ++ip) {
base_node n(dim2);
for (size_type j=0, cnt=0; j < dim; ++j) if (!direction_useless[j])
n[cnt++]=gid_nodes[ip][j];
- msh_node_2_getfem_node[ip] = m.add_point(n);
+ msh_node_2_getfem_node[ip]
+ = m.add_point(n, merge_overlapping_nodes ? 0. : -1.);
}
}
bgeot::read_until(f, "ELEMENTS");
- bgeot::pgeometric_trans pgt = NULL;
+ bgeot::pgeometric_trans pgt = nullptr;
std::vector<size_type> order(nnode); // ordre de GiD cf
http://gid.cimne.upc.es/support/gid_11.subst#SEC160
for (size_type i=0; i < nnode; ++i) order[i]=i;
//cerr << "reading elements " << std::streamoff(f.tellg()) << "\n";
@@ -747,7 +833,7 @@ namespace getfem {
} break;
default: GMM_ASSERT1(false, ""); break;
}
- GMM_ASSERT1(pgt != NULL, "unknown element type " << selemtype
+ GMM_ASSERT1(pgt != nullptr, "unknown element type " << selemtype
<< " with " << nnode << "nodes");
do {
std::string ls;
@@ -780,6 +866,7 @@ namespace getfem {
} while (!f.eof());
}
+
/* mesh file from ANSYS
Supports solid structural elements stored with cdwrite in blocked format.
@@ -787,9 +874,9 @@ namespace getfem {
cdwrite,db,filename,cdb
*/
- static void import_cdb_mesh_file(std::istream& f, mesh& m,
- size_type imat_filt=size_type(-1)) {
-
+ static void import_cdb_mesh(std::istream& f, mesh& m,
+ size_type imat_filt=size_type(-1),
+ bool merge_overlapping_nodes=false) {
std::map<size_type, size_type> cdb_node_2_getfem_node;
std::vector<size_type> getfem_cv_nodes;
std::vector<std::string> elt_types;
@@ -894,7 +981,8 @@ namespace getfem {
else
pt[j] = 0;
- cdb_node_2_getfem_node[nodeid] = m.add_point(pt, -1.);
+ cdb_node_2_getfem_node[nodeid]
+ = m.add_point(pt, merge_overlapping_nodes ? 0. : -1.);
}
while (bgeot::casecmp(line.substr(0,6),"EBLOCK") != 0) {
@@ -952,7 +1040,7 @@ namespace getfem {
if (nodesno >= 8) PP = std::stol(line.substr(7*fieldwidth,fieldwidth));
if (nodesno >= 9) {
std::getline(f,line);
- if (nodesno >= 9) QQ = std::stol(line.substr(0,fieldwidth));
+ QQ = std::stol(line.substr(0,fieldwidth));
if (nodesno >= 10) RR =
std::stol(line.substr(1*fieldwidth,fieldwidth));
if (nodesno >= 11) SS =
std::stol(line.substr(2*fieldwidth,fieldwidth));
if (nodesno >= 12) TT =
std::stol(line.substr(3*fieldwidth,fieldwidth));
@@ -1253,8 +1341,8 @@ namespace getfem {
}
int nonempty_regions=0;
- for (size_type i=0; i < regions.size(); ++i)
- if (regions[i].card() > 0)
+ for (const dal::bit_vector ®ion : regions)
+ if (region.card() > 0)
++nonempty_regions;
if (nonempty_regions > 1)
@@ -1270,23 +1358,10 @@ namespace getfem {
}
- static double round_to_nth_significant_number(double x, int ndec) {
- double p = 1.;
- double s = (x < 0 ? -1 : 1);
- double pdec = pow(10.,double(ndec));
- if (x == 0) return 0.;
- x = gmm::abs(x);
- while (x > 1) { x /= 10.0; p*=10; }
- while (x < 0.1) { x *= 10.0; p/=10; }
- //cerr << "x=" << x << ", p=" << p << ", pdec=" << pdec << "\n";
- x = s * (floor(x * pdec + 0.5) / pdec) * p;
- return x;
- }
-
/* mesh file from noboite [http://www.distene.com/fr/corp/newsroom16.html] */
- static void import_noboite_mesh_file(std::istream& f, mesh& m) {
-
+ static void import_noboite_mesh(std::istream& f, mesh& m)
+ {
using namespace std;
gmm::stream_standard_locale sl(f);
@@ -1369,19 +1444,35 @@ namespace getfem {
else // sinon
cerr << "Erreur à l'ouverture !" << endl;
- // appeler sunroutine import_gid_mesh_file
+ // appeler subroutine import_gid_mesh
//import_mesh(const std::string& "noboite_to_GiD.gid", mesh& msh)
- ifstream fichier1_GiD("noboite_to_GiD.gid", ios::in);
- import_gid_mesh_file(fichier1_GiD, m);
+ ifstream file1_GiD("noboite_to_GiD.gid", ios::in);
+ import_gid_mesh(file1_GiD, m);
// return 0;
}
+
+
/* mesh file from emc2
[http://pauillac.inria.fr/cdrom/prog/unix/emc2/eng.htm], am_fmt format
(only triangular 2D meshes)
*/
- static void import_am_fmt_mesh_file(std::istream& f, mesh& m) {
+
+ static double round_to_nth_significant_number(double x, int ndec) {
+ double p = 1.;
+ double s = (x < 0 ? -1 : 1);
+ double pdec = pow(10.,double(ndec));
+ if (x == 0) return 0.;
+ x = gmm::abs(x);
+ while (x > 1) { x /= 10.0; p*=10; }
+ while (x < 0.1) { x *= 10.0; p/=10; }
+ //cerr << "x=" << x << ", p=" << p << ", pdec=" << pdec << "\n";
+ x = s * (floor(x * pdec + 0.5) / pdec) * p;
+ return x;
+ }
+
+ static void import_am_fmt_mesh(std::istream& f, mesh& m) {
gmm::stream_standard_locale sl(f);
/* read the node list */
std::vector<size_type> tri;
@@ -1395,18 +1486,19 @@ namespace getfem {
cerr.precision(16);
P[0]=round_to_nth_significant_number(P[0],6); // force 9.999999E-1 to be
converted to 1.0
P[1]=round_to_nth_significant_number(P[1],6);
- size_type jj = m.add_point(P);
+ size_type jj = m.add_point(P, -1.);
GMM_ASSERT1(jj == j, "ouch");
}
for (size_type i=0; i < nbt*3; i+=3)
m.add_triangle(tri[i]-1,tri[i+1]-1,tri[i+2]-1);
}
+
/* mesh file from emc2
[http://pauillac.inria.fr/cdrom/prog/unix/emc2/eng.htm], am_fmt format
triangular/quadrangular 2D meshes
*/
- static void import_emc2_mesh_file(std::istream& f, mesh& m) {
+ static void import_emc2_mesh(std::istream& f, mesh& m) {
gmm::stream_standard_locale sl(f);
/* read the node list */
std::vector<size_type> tri;
@@ -1416,7 +1508,7 @@ namespace getfem {
f >> nbs;
for (size_type j=0; j < nbs; ++j) {
f >> P[0] >> P[1] >> dummy;
- size_type jj = m.add_point(P);
+ size_type jj = m.add_point(P, -1.);
GMM_ASSERT1(jj == j, "ouch");
}
while (!f.eof()) {
@@ -1439,122 +1531,33 @@ namespace getfem {
}
}
- void import_mesh(const std::string& filename, const std::string& format,
- mesh& m) {
- m.clear();
- try {
-
- if (bgeot::casecmp(format,"structured")==0)
- { regular_mesh(m, filename); return; }
- else if (bgeot::casecmp(format,"structured_ball")==0)
- { regular_ball_mesh(m, filename); return; }
- else if (bgeot::casecmp(format,"structured_ball_shell")==0)
- { regular_ball_shell_mesh(m, filename); return; }
- std::ifstream f(filename.c_str());
- GMM_ASSERT1(f.good(), "can't open file " << filename);
- /* throw exceptions when an error occurs */
- f.exceptions(std::ifstream::badbit | std::ifstream::failbit);
- import_mesh(f, format, m);
- f.close();
- }
- catch (std::logic_error& exc) {
- m.clear();
- throw exc;
- }
- catch (std::ios_base::failure& exc) {
- m.clear();
- GMM_ASSERT1(false, "error while importing " << format
- << " mesh file \"" << filename << "\" : " << exc.what());
- }
- catch (std::runtime_error& exc) {
- m.clear();
- throw exc;
- }
- }
-
- void import_mesh_gmsh(std::istream& f, mesh &m,
- std::map<std::string, size_type> ®ion_map,
- bool remove_last_dimension,
- std::map<size_type, std::set<size_type>> *nodal_map,
- bool remove_duplicated_nodes)
+ // Main dispatcher to all supported file formats
+ void import_mesh(std::istream& f, const std::string& format, mesh& m)
{
- import_gmsh_mesh_file(f, m, 0, ®ion_map, nullptr, false,
remove_last_dimension, nodal_map,
- remove_duplicated_nodes);
- }
-
- void import_mesh_gmsh(std::istream& f, mesh& m,
- bool add_all_element_type,
- std::set<size_type> *lower_dim_convex_rg,
- std::map<std::string, size_type> *region_map,
- bool remove_last_dimension,
- std::map<size_type, std::set<size_type>> *nodal_map,
- bool remove_duplicated_nodes)
- {
- import_gmsh_mesh_file(f, m, 0, region_map, lower_dim_convex_rg,
add_all_element_type,
- remove_last_dimension, nodal_map,
remove_duplicated_nodes);
- }
-
- void import_mesh_gmsh(const std::string& filename, mesh& m,
- bool add_all_element_type,
- std::set<size_type> *lower_dim_convex_rg,
- std::map<std::string, size_type> *region_map,
- bool remove_last_dimension,
- std::map<size_type, std::set<size_type>> *nodal_map,
- bool remove_duplicated_nodes)
- {
- m.clear();
- try {
- std::ifstream f(filename.c_str());
- GMM_ASSERT1(f.good(), "can't open file " << filename);
- /* throw exceptions when an error occurs */
- f.exceptions(std::ifstream::badbit | std::ifstream::failbit);
- import_gmsh_mesh_file(f, m, 0, region_map, lower_dim_convex_rg,
add_all_element_type,
- remove_last_dimension, nodal_map,
remove_duplicated_nodes);
- f.close();
- }
- catch (std::logic_error& exc) {
- m.clear();
- throw exc;
- }
- catch (std::ios_base::failure& exc) {
- m.clear();
- GMM_ASSERT1(false, "error while importing " << "gmsh"
- << " mesh file \"" << filename << "\" : " << exc.what());
+ std::string fmt(format);
+ bool merge_overlapping_nodes = false;
+ size_type pos = format.find(":merge_overlapping_nodes");
+ if (pos != std::string::npos) {
+ merge_overlapping_nodes = true;
+ fmt = format.substr(0,pos) + format.substr(pos+24);
+ GMM_ASSERT2(fmt.find(":merge_overlapping_nodes") == std::string::npos,
+ "Invalid mesh format syntax: "+format);
}
- catch (std::runtime_error& exc) {
- m.clear();
- throw exc;
- }
- }
-
- void import_mesh_gmsh(const std::string& filename,
- mesh& m, std::map<std::string, size_type> ®ion_map,
- bool remove_last_dimension,
- std::map<size_type, std::set<size_type>> *nodal_map,
- bool remove_duplicated_nodes) {
- import_mesh_gmsh(filename, m, false, NULL, ®ion_map,
remove_last_dimension, nodal_map,
- remove_duplicated_nodes);
- }
-
- void import_mesh(std::istream& f, const std::string& format,
- mesh& m) {
- if (bgeot::casecmp(format,"gmsh")==0)
- import_gmsh_mesh_file(f,m);
- else if (bgeot::casecmp(format,"gmsh_with_lower_dim_elt")==0)
- import_gmsh_mesh_file(f,m,0,NULL,NULL,true);
- else if (bgeot::casecmp(format,"gmshv2")==0)/* deprecate */
- import_gmsh_mesh_file(f,m,2);
- else if (bgeot::casecmp(format,"gid")==0)
- import_gid_mesh_file(f,m);
- else if (bgeot::casecmp(format,"noboite")==0)
- import_noboite_mesh_file(f,m);
- else if (bgeot::casecmp(format,"am_fmt")==0)
- import_am_fmt_mesh_file(f,m);
- else if (bgeot::casecmp(format,"emc2_mesh")==0)
- import_emc2_mesh_file(f,m);
- else if (bgeot::casecmp(format,"cdb")==0)
- import_cdb_mesh_file(f,m);
+ if (bgeot::casecmp(fmt,"gmsh")==0)
+ import_gmsh_mesh(f,m);
+ else if (bgeot::casecmp(fmt,"gmsh_with_lower_dim_elt")==0)
+ import_gmsh_mesh(f,m,true,nullptr,nullptr);
+ else if (bgeot::casecmp(fmt,"gid")==0)
+ import_gid_mesh(f,m);
+ else if (bgeot::casecmp(fmt,"noboite")==0)
+ import_noboite_mesh(f,m);
+ else if (bgeot::casecmp(fmt,"am_fmt")==0)
+ import_am_fmt_mesh(f,m);
+ else if (bgeot::casecmp(fmt,"emc2_mesh")==0)
+ import_emc2_mesh(f,m);
+ else if (bgeot::casecmp(fmt,"cdb")==0)
+ import_cdb_mesh(f,m);
else if (bgeot::casecmp(format.substr(0,4),"cdb:")==0) {
size_type imat(-1);
bool success(true);
@@ -1568,7 +1571,7 @@ namespace getfem {
success = false;
}
if (success)
- import_cdb_mesh_file(f,m,imat);
+ import_cdb_mesh(f,m,imat);
else GMM_ASSERT1(false, "cannot import "
<< format << " mesh type : wrong cdb mesh type input");
}
@@ -1576,24 +1579,4 @@ namespace getfem {
<< format << " mesh type : unknown mesh type");
}
- void import_mesh(const std::string& filename, mesh& msh) {
- size_type pos = filename.find_last_of(":");
- if (pos != std::string::npos)
- getfem::import_mesh(filename.substr(pos+1), filename.substr(0,pos), msh);
- else
- msh.read_from_file(filename);
- }
-
- void maybe_remove_last_dimension(mesh &m) {
- bool is_flat = true;
- unsigned N = m.dim(); if (N < 1) return;
- for (dal::bv_visitor i(m.points().index()); !i.finished(); ++i)
- if (m.points()[i][N-1] != 0) is_flat = 0;
- if (is_flat) {
- base_matrix M(N-1,N);
- for (unsigned i=0; i < N-1; ++i) M(i,i) = 1;
- m.transformation(M);
- }
- }
-
}