OGS
convertMeshToGeo.cpp
Go to the documentation of this file.
1 
15 #include "convertMeshToGeo.h"
16 
17 #include "BaseLib/Logging.h"
18 #include "Elements/Quad.h"
19 #include "Elements/Tri.h"
20 #include "GeoLib/GEOObjects.h"
21 #include "GeoLib/Surface.h"
22 #include "GeoLib/Triangle.h"
23 #include "Mesh.h"
25 #include "MeshInformation.h"
26 
27 namespace
28 {
32  double const eps,
33  GeoLib::GEOObjects& geo_objects)
34 {
35  std::vector<GeoLib::Point*> points;
36  points.reserve(mesh.getNumberOfNodes());
37 
38  std::transform(begin(mesh.getNodes()), end(mesh.getNodes()),
39  std::back_inserter(points),
40  [](MeshLib::Node const* node_ptr)
41  { return new GeoLib::Point(*node_ptr, node_ptr->getID()); });
42 
43  auto geoobject_name = mesh.getName(); // Possibly modified when adding
44  // points to the geo objects.
45  geo_objects.addPointVec(std::move(points), geoobject_name, {}, eps);
46  return geoobject_name;
47 }
48 
50  std::vector<std::size_t> const& id_map,
51  GeoLib::Surface& surface)
52 {
54  {
55  surface.addTriangle(id_map[getNodeIndex(e, 0)],
56  id_map[getNodeIndex(e, 1)],
57  id_map[getNodeIndex(e, 2)]);
58  return;
59  }
61  {
62  surface.addTriangle(id_map[getNodeIndex(e, 0)],
63  id_map[getNodeIndex(e, 1)],
64  id_map[getNodeIndex(e, 2)]);
65  surface.addTriangle(id_map[getNodeIndex(e, 0)],
66  id_map[getNodeIndex(e, 2)],
67  id_map[getNodeIndex(e, 3)]);
68  return;
69  }
70  // all other element types are ignored (i.e. lines)
71 };
72 
73 } // namespace
74 
75 namespace MeshLib
76 {
78  GeoLib::GEOObjects& geo_objects,
79  double const eps)
80 {
81  if (mesh.getDimension() != 2)
82  {
83  ERR("Mesh to geometry conversion is only working for 2D meshes.");
84  return false;
85  }
86 
87  // Special handling of the bounds in case there are no materialIDs present.
88  auto get_material_ids_and_bounds = [&]()
89  -> std::tuple<MeshLib::PropertyVector<int> const*, std::pair<int, int>>
90  {
91  auto const materialIds = materialIDs(mesh);
92  if (!materialIds)
93  {
94  return std::make_tuple(nullptr, std::make_pair(0, 0));
95  }
96 
97  auto const bounds = MeshInformation::getValueBounds(*materialIds);
98  if (!bounds)
99  {
100  OGS_FATAL(
101  "Could not get minimum/maximum ranges values for the "
102  "MaterialIDs property in the mesh '{:s}'.",
103  mesh.getName());
104  }
105  return std::make_tuple(materialIds, *bounds);
106  };
107 
108  auto const [materialIds, bounds] = get_material_ids_and_bounds();
109  // elements to surface triangles conversion
110  const unsigned nMatGroups(bounds.second - bounds.first + 1);
111  std::vector<GeoLib::Surface*> sfcs;
112  sfcs.reserve(nMatGroups);
113  std::string const geoobject_name =
114  convertMeshNodesToGeoPoints(mesh, eps, geo_objects);
115  auto const& points = *geo_objects.getPointVec(geoobject_name);
116  for (unsigned i = 0; i < nMatGroups; ++i)
117  {
118  sfcs.push_back(new GeoLib::Surface(points));
119  }
120 
121  const std::vector<std::size_t>& id_map(
122  geo_objects.getPointVecObj(geoobject_name)->getIDMap());
123  const std::vector<MeshLib::Element*>& elements = mesh.getElements();
124  const std::size_t nElems(mesh.getNumberOfElements());
125 
126  for (unsigned i = 0; i < nElems; ++i)
127  {
128  auto surfaceId = !materialIds ? 0 : ((*materialIds)[i] - bounds.first);
129  addElementToSurface(*elements[i], id_map, *sfcs[surfaceId]);
130  }
131 
132  std::for_each(sfcs.begin(), sfcs.end(),
133  [](GeoLib::Surface*& sfc)
134  {
135  if (sfc->getNumberOfTriangles() == 0)
136  {
137  delete sfc;
138  sfc = nullptr;
139  }
140  });
141  auto sfcs_end = std::remove(sfcs.begin(), sfcs.end(), nullptr);
142  sfcs.erase(sfcs_end, sfcs.end());
143 
144  geo_objects.addSurfaceVec(std::move(sfcs), geoobject_name,
146  return true;
147 }
148 
150  const std::string& mesh_name,
151  double eps)
152 {
153  // convert to a mesh including duplicated nodes
154  std::vector<MeshLib::Node*> nodes;
155  std::vector<MeshLib::Element*> elements;
156  std::size_t nodeId = 0;
157  for (std::size_t i = 0; i < sfc.getNumberOfTriangles(); i++)
158  {
159  auto* tri = sfc[i];
160  auto** tri_nodes = new MeshLib::Node*[3];
161  for (unsigned j = 0; j < 3; j++)
162  {
163  tri_nodes[j] =
164  new MeshLib::Node(tri->getPoint(j)->getCoords(), nodeId++);
165  }
166  elements.push_back(new MeshLib::Tri(tri_nodes, i));
167  for (unsigned j = 0; j < 3; j++)
168  {
169  nodes.push_back(tri_nodes[j]);
170  }
171  }
172  MeshLib::Mesh mesh_with_duplicated_nodes(mesh_name, nodes, elements);
173 
174  // remove duplicated nodes
175  MeshLib::MeshRevision rev(mesh_with_duplicated_nodes);
176  return rev.simplifyMesh(mesh_with_duplicated_nodes.getName(), eps);
177 }
178 
179 } // namespace MeshLib
#define OGS_FATAL(...)
Definition: Error.h:26
Definition of the GEOObjects class.
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
Definition of the MeshInformation class.
Definition of the MeshRevision class.
Definition of the Mesh class.
Definition of the Quad class.
Definition of the Tri class.
Container class for geometric objects.
Definition: GEOObjects.h:61
const std::vector< Point * > * getPointVec(const std::string &name) const
Definition: GEOObjects.cpp:72
void addPointVec(std::vector< Point * > &&points, std::string &name, PointVec::NameIdMap &&pnt_id_name_map, double const eps=std::sqrt(std::numeric_limits< double >::epsilon()))
Definition: GEOObjects.cpp:47
const PointVec * getPointVecObj(const std::string &name) const
Definition: GEOObjects.cpp:85
const std::vector< std::size_t > & getIDMap() const
Definition: PointVec.h:96
A Surface is represented by Triangles. It consists of a reference to a vector of (pointers to) points...
Definition: Surface.h:34
std::size_t getNumberOfTriangles() const
Definition: Surface.cpp:82
void addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c)
Definition: Surface.cpp:49
std::map< std::string, std::size_t > NameIdMap
Definition: TemplateVec.h:44
virtual MeshElemType getGeomType() const =0
static std::optional< std::pair< T, T > > const getValueBounds(PropertyVector< T > const &property)
MeshLib::Mesh * simplifyMesh(const std::string &new_mesh_name, double eps, unsigned min_elem_dim=1) const
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition: Mesh.h:95
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition: Mesh.h:71
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition: Mesh.h:98
const std::string getName() const
Get name of the mesh.
Definition: Mesh.h:92
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition: Mesh.h:89
std::size_t getNumberOfElements() const
Get the number of elements.
Definition: Mesh.h:86
Definition of mesh to geometry conversion.
bool convertMeshToGeo(const MeshLib::Mesh &mesh, GeoLib::GEOObjects &geo_objects, double const eps)
MeshLib::Mesh * convertSurfaceToMesh(const GeoLib::Surface &sfc, const std::string &mesh_name, double eps)
PropertyVector< int > const * materialIDs(Mesh const &mesh)
Definition: Mesh.cpp:258
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition: Element.cpp:225
void addElementToSurface(MeshLib::Element const &e, std::vector< std::size_t > const &id_map, GeoLib::Surface &surface)
std::string convertMeshNodesToGeoPoints(MeshLib::Mesh const &mesh, double const eps, GeoLib::GEOObjects &geo_objects)