getfem-commits
[Top][All Lists]
Advanced

[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> &region_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> &region_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, &region_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> &region_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, &region_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 &region : 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> &region_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, &region_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> &region_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, &region_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);
-    }
-  }
-
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]