OGS
MeshLib::MeshSurfaceExtraction Class Reference

Detailed Description

A set of tools concerned with extracting nodes and elements from a mesh surface.

Definition at line 36 of file MeshSurfaceExtraction.h.

#include <MeshSurfaceExtraction.h>

Static Public Member Functions

static std::vector< double > getSurfaceAreaForNodes (const MeshLib::Mesh &mesh)
 Returns a vector of the areas assigned to each node on a surface mesh. More...
 
static std::vector< MeshLib::Node * > getSurfaceNodes (const MeshLib::Mesh &mesh, Eigen::Vector3d const &dir, double angle)
 Returns the surface nodes of a mesh. More...
 
static MeshLib::MeshgetMeshSurface (const MeshLib::Mesh &subsfc_mesh, Eigen::Vector3d const &dir, double angle, std::string const &subsfc_node_id_prop_name="", std::string const &subsfc_element_id_prop_name="", std::string const &face_id_prop_name="")
 

Static Private Member Functions

static void get2DSurfaceElements (const std::vector< MeshLib::Element * > &all_elements, std::vector< MeshLib::Element * > &sfc_elements, std::vector< std::size_t > &element_to_bulk_element_id_map, std::vector< std::size_t > &element_to_bulk_face_id_map, Eigen::Vector3d const &dir, double angle, unsigned mesh_dimension)
 Functionality needed for getSurfaceNodes() and getMeshSurface() More...
 

Member Function Documentation

◆ get2DSurfaceElements()

void MeshLib::MeshSurfaceExtraction::get2DSurfaceElements ( const std::vector< MeshLib::Element * > &  all_elements,
std::vector< MeshLib::Element * > &  sfc_elements,
std::vector< std::size_t > &  element_to_bulk_element_id_map,
std::vector< std::size_t > &  element_to_bulk_face_id_map,
Eigen::Vector3d const &  dir,
double  angle,
unsigned  mesh_dimension 
)
staticprivate

Functionality needed for getSurfaceNodes() and getMeshSurface()

Definition at line 285 of file MeshSurfaceExtraction.cpp.

291 {
292  if (mesh_dimension < 2 || mesh_dimension > 3)
293  {
294  ERR("Cannot handle meshes of dimension {:i}", mesh_dimension);
295  }
296 
297  bool const complete_surface = (dir.dot(dir) == 0);
298 
299  double const pi(boost::math::constants::pi<double>());
300  double const cos_theta(std::cos(angle * pi / 180.0));
301  Eigen::Vector3d const norm_dir(dir.normalized());
302 
303  for (auto const* elem : all_elements)
304  {
305  const unsigned element_dimension(elem->getDimension());
306  if (element_dimension < mesh_dimension)
307  {
308  continue;
309  }
310 
311  if (element_dimension == 2)
312  {
313  if (!complete_surface)
314  {
315  if (FaceRule::getSurfaceNormal(*elem).normalized().dot(
316  norm_dir) > cos_theta)
317  {
318  continue;
319  }
320  }
321  sfc_elements.push_back(elem->clone());
322  element_to_bulk_element_id_map.push_back(elem->getID());
323  element_to_bulk_face_id_map.push_back(0);
324  }
325  else
326  {
327  if (!elem->isBoundaryElement())
328  {
329  continue;
330  }
331  const unsigned nFaces(elem->getNumberOfFaces());
332  for (unsigned j = 0; j < nFaces; ++j)
333  {
334  if (elem->getNeighbor(j) != nullptr)
335  {
336  continue;
337  }
338 
339  auto const face =
340  std::unique_ptr<MeshLib::Element const>{elem->getFace(j)};
341  if (!complete_surface)
342  {
343  if (FaceRule::getSurfaceNormal(*face).normalized().dot(
344  norm_dir) < cos_theta)
345  {
346  continue;
347  }
348  }
349  if (face->getGeomType() == MeshElemType::TRIANGLE)
350  {
351  sfc_elements.push_back(new MeshLib::Tri(
352  *static_cast<const MeshLib::Tri*>(face.get())));
353  }
354  else
355  {
356  sfc_elements.push_back(new MeshLib::Quad(
357  *static_cast<const MeshLib::Quad*>(face.get())));
358  }
359  element_to_bulk_element_id_map.push_back(elem->getID());
360  element_to_bulk_face_id_map.push_back(j);
361  }
362  }
363  }
364 }
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
static Eigen::Vector3d getSurfaceNormal(Element const &e)
Returns the surface normal of a 2D element.
Definition: FaceRule.cpp:40

References ERR(), MeshLib::FaceRule::getSurfaceNormal(), and MeshLib::TRIANGLE.

Referenced by getMeshSurface(), and getSurfaceNodes().

◆ getMeshSurface()

MeshLib::Mesh * MeshLib::MeshSurfaceExtraction::getMeshSurface ( const MeshLib::Mesh subsfc_mesh,
Eigen::Vector3d const &  dir,
double  angle,
std::string const &  subsfc_node_id_prop_name = "",
std::string const &  subsfc_element_id_prop_name = "",
std::string const &  face_id_prop_name = "" 
)
static

Returns the 2d-element mesh representing the surface of the given mesh.

Parameters
subsfc_meshThe original mesh
dirThe direction in which face normals have to point to be considered surface elements
angleThe angle of the allowed deviation from the given direction (0 <= angle <= 90 degrees)
subsfc_node_id_prop_nameThe name of the PropertyVector in the surface mesh the subsurface mesh node ids are stored to. If the string is empty, there won't be such a PropertyVector.
subsfc_element_id_prop_nameThe name of the PropertyVector in the surface mesh that stores the subsurface element ids. If the string is empty, there won't be such a PropertyVector.
face_id_prop_nameThe name of the PropertyVector in the surface mesh that stores the face number of the subsurface element that belongs to the boundary. If the string is empty, there won't be such a PropertyVector.
Returns
A 2D mesh representing the surface in direction dir

Definition at line 229 of file MeshSurfaceExtraction.cpp.

234 {
235  // allow slightly greater angles than 90 degrees for numerical errors
236  if (angle < 0 || angle > 91)
237  {
238  ERR("Supported angle between 0 and 90 degrees only.");
239  return nullptr;
240  }
241 
242  INFO("Extracting mesh surface...");
243  std::vector<MeshLib::Element*> sfc_elements;
244  std::vector<std::size_t> element_ids_map;
245  std::vector<std::size_t> face_ids_map;
246  get2DSurfaceElements(subsfc_mesh.getElements(), sfc_elements,
247  element_ids_map, face_ids_map, dir, angle,
248  subsfc_mesh.getDimension());
249 
250  if (sfc_elements.empty())
251  {
252  return nullptr;
253  }
254 
255  auto [sfc_nodes, node_id_map] = createNodesAndIDMapFromElements(
256  sfc_elements, subsfc_mesh.getNumberOfNodes());
257 
258  // create new elements vector with newly created nodes (and delete
259  // temp-elements)
260  auto new_elements =
261  MeshLib::copyElementVector(sfc_elements, sfc_nodes, &node_id_map);
262  std::for_each(sfc_elements.begin(), sfc_elements.end(),
263  [](MeshLib::Element* e) { delete e; });
264 
265  std::vector<std::size_t> id_map;
266  id_map.reserve(sfc_nodes.size());
267  std::transform(begin(sfc_nodes), end(sfc_nodes), std::back_inserter(id_map),
268  [](MeshLib::Node* const n) { return n->getID(); });
269 
270  MeshLib::Mesh* result(
271  new Mesh(subsfc_mesh.getName() + "-Surface", sfc_nodes, new_elements));
272 
273  addBulkIDPropertiesToMesh(*result, subsfc_node_id_prop_name, id_map,
274  subsfc_element_id_prop_name, element_ids_map,
275  face_id_prop_name, face_ids_map);
276 
277  if (!createSfcMeshProperties(*result, subsfc_mesh.getProperties(), id_map,
278  element_ids_map))
279  {
280  ERR("Transferring subsurface properties failed.");
281  }
282  return result;
283 }
void INFO(char const *fmt, Args const &... args)
Definition: Logging.h:32
std::size_t getID() const
Definition: Point3dWithID.h:62
static void get2DSurfaceElements(const std::vector< MeshLib::Element * > &all_elements, std::vector< MeshLib::Element * > &sfc_elements, std::vector< std::size_t > &element_to_bulk_element_id_map, std::vector< std::size_t > &element_to_bulk_face_id_map, Eigen::Vector3d const &dir, double angle, unsigned mesh_dimension)
Functionality needed for getSurfaceNodes() and getMeshSurface()
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
Properties & getProperties()
Definition: Mesh.h:123
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition: Mesh.h:89
bool createSfcMeshProperties(MeshLib::Mesh &sfc_mesh, MeshLib::Properties const &properties, std::vector< std::size_t > const &node_ids_map, std::vector< std::size_t > const &element_ids_map)
std::tuple< std::vector< MeshLib::Node * >, std::vector< std::size_t > > createNodesAndIDMapFromElements(std::vector< MeshLib::Element * > const &elements, std::size_t const n_all_nodes)
void addBulkIDPropertiesToMesh(MeshLib::Mesh &surface_mesh, std::string const &node_to_bulk_node_id_map_name, std::vector< std::size_t > const &node_to_bulk_node_id_map, std::string const &element_to_bulk_element_id_map_name, std::vector< std::size_t > const &element_to_bulk_element_id_map, std::string const &element_to_bulk_face_id_map_name, std::vector< std::size_t > const &element_to_bulk_face_id_map)
std::vector< Element * > copyElementVector(std::vector< Element * > const &elements, std::vector< Node * > const &new_nodes, std::vector< std::size_t > const *const node_id_map)

References MeshLib::addBulkIDPropertiesToMesh(), MeshLib::copyElementVector(), MeshLib::createNodesAndIDMapFromElements(), MeshLib::createSfcMeshProperties(), ERR(), get2DSurfaceElements(), MeshLib::Mesh::getDimension(), MeshLib::Mesh::getElements(), MathLib::Point3dWithID::getID(), MeshLib::Mesh::getName(), MeshLib::Mesh::getNumberOfNodes(), MeshLib::Mesh::getProperties(), and INFO().

Referenced by MeshLib::addLayerToMesh(), MeshGeoToolsLib::GeoMapper::advancedMapOnMesh(), DirectConditionGenerator::directWithSurfaceIntegration(), MeshView::extractSurfaceMesh(), main(), and MeshGeoToolsLib::GeoMapper::mapOnMesh().

◆ getSurfaceAreaForNodes()

std::vector< double > MeshLib::MeshSurfaceExtraction::getSurfaceAreaForNodes ( const MeshLib::Mesh mesh)
static

Returns a vector of the areas assigned to each node on a surface mesh.

Definition at line 188 of file MeshSurfaceExtraction.cpp.

190 {
191  std::vector<double> node_area_vec;
192  if (mesh.getDimension() != 2)
193  {
194  ERR("Error in MeshSurfaceExtraction::getSurfaceAreaForNodes() - Given "
195  "mesh is no surface mesh (dimension != 2).");
196  return node_area_vec;
197  }
198 
199  double total_area(0);
200 
201  // for each node, a vector containing all the element idget every element
202  const std::vector<MeshLib::Node*>& nodes = mesh.getNodes();
203  const std::size_t nNodes(mesh.getNumberOfNodes());
204  for (std::size_t n = 0; n < nNodes; ++n)
205  {
206  double node_area(0);
207 
208  auto const conn_elems = mesh.getElementsConnectedToNode(*nodes[n]);
209  const std::size_t nConnElems(conn_elems.size());
210 
211  for (std::size_t i = 0; i < nConnElems; ++i)
212  {
213  const MeshLib::Element* elem(conn_elems[i]);
214  const unsigned nElemParts =
215  (elem->getGeomType() == MeshElemType::TRIANGLE) ? 3 : 4;
216  const double area = conn_elems[i]->getContent() / nElemParts;
217  node_area += area;
218  total_area += area;
219  }
220 
221  node_area_vec.push_back(node_area);
222  }
223 
224  INFO("Total surface Area: {:f}", total_area);
225 
226  return node_area_vec;
227 }
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition: Mesh.h:95
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
Definition: Mesh.cpp:232

References ERR(), MeshLib::Mesh::getDimension(), MeshLib::Mesh::getElementsConnectedToNode(), MeshLib::Element::getGeomType(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getNumberOfNodes(), INFO(), and MeshLib::TRIANGLE.

Referenced by DirectConditionGenerator::directWithSurfaceIntegration(), and main().

◆ getSurfaceNodes()

std::vector< MeshLib::Node * > MeshLib::MeshSurfaceExtraction::getSurfaceNodes ( const MeshLib::Mesh mesh,
Eigen::Vector3d const &  dir,
double  angle 
)
static

Returns the surface nodes of a mesh.

Definition at line 366 of file MeshSurfaceExtraction.cpp.

368 {
369  INFO("Extracting surface nodes...");
370  std::vector<MeshLib::Element*> sfc_elements;
371  std::vector<std::size_t> element_to_bulk_element_id_map;
372  std::vector<std::size_t> element_to_bulk_face_id_map;
373 
375  mesh.getElements(), sfc_elements, element_to_bulk_element_id_map,
376  element_to_bulk_face_id_map, dir, angle, mesh.getDimension());
377 
378  std::vector<MeshLib::Node*> surface_nodes;
379  std::tie(surface_nodes, std::ignore) =
381 
382  for (auto e : sfc_elements)
383  {
384  delete e;
385  }
386 
387  return surface_nodes;
388 }

References MeshLib::createNodesAndIDMapFromElements(), get2DSurfaceElements(), MeshLib::Mesh::getDimension(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getNumberOfNodes(), and INFO().

Referenced by DirectConditionGenerator::directToSurfaceNodes(), and main().


The documentation for this class was generated from the following files: