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  auto points = std::make_unique<std::vector<GeoLib::Point*>>();
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, nullptr, 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  auto sfcs = std::make_unique<std::vector<GeoLib::Surface*>>();
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);
145  return true;
146 }
147 
149  const std::string& mesh_name,
150  double eps)
151 {
152  // convert to a mesh including duplicated nodes
153  std::vector<MeshLib::Node*> nodes;
154  std::vector<MeshLib::Element*> elements;
155  std::size_t nodeId = 0;
156  for (std::size_t i = 0; i < sfc.getNumberOfTriangles(); i++)
157  {
158  auto* tri = sfc[i];
159  auto** tri_nodes = new MeshLib::Node*[3];
160  for (unsigned j = 0; j < 3; j++)
161  {
162  tri_nodes[j] =
163  new MeshLib::Node(tri->getPoint(j)->getCoords(), nodeId++);
164  }
165  elements.push_back(new MeshLib::Tri(tri_nodes, i));
166  for (unsigned j = 0; j < 3; j++)
167  {
168  nodes.push_back(tri_nodes[j]);
169  }
170  }
171  MeshLib::Mesh mesh_with_duplicated_nodes(mesh_name, nodes, elements);
172 
173  // remove duplicated nodes
174  MeshLib::MeshRevision rev(mesh_with_duplicated_nodes);
175  return rev.simplifyMesh(mesh_with_duplicated_nodes.getName(), eps);
176 }
177 
178 } // 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:71
const PointVec * getPointVecObj(const std::string &name) const
Definition: GEOObjects.cpp:84
void addPointVec(std::unique_ptr< std::vector< Point * >> points, std::string &name, std::unique_ptr< std::map< std::string, std::size_t >> pnt_id_name_map=nullptr, double eps=std::sqrt(std::numeric_limits< double >::epsilon()))
Definition: GEOObjects.cpp:51
const std::vector< std::size_t > & getIDMap() const
Definition: PointVec.h:97
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
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)