OGS
MeshToolsLib::MeshSurfaceExtraction Class Reference

Detailed Description

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

Definition at line 38 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.
 
static std::vector< MeshLib::Node * > getSurfaceNodes (const MeshLib::Mesh &mesh, Eigen::Vector3d const &dir, double angle)
 Returns the surface nodes of a mesh.
 
static MeshLib::MeshgetMeshSurface (const MeshLib::Mesh &subsfc_mesh, Eigen::Vector3d const &dir, double angle, std::string_view subsfc_node_id_prop_name="", std::string_view subsfc_element_id_prop_name="", std::string_view 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()
 

Member Function Documentation

◆ get2DSurfaceElements()

void MeshToolsLib::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 300 of file MeshSurfaceExtraction.cpp.

306{
307 if (mesh_dimension < 2 || mesh_dimension > 3)
308 {
309 ERR("Cannot handle meshes of dimension {}", mesh_dimension);
310 }
311
312 bool const complete_surface = (dir.dot(dir) == 0);
313
314 double const cos_theta(std::cos(angle * std::numbers::pi / 180.0));
315 Eigen::Vector3d const norm_dir(dir.normalized());
316
317 for (auto const* elem : all_elements)
318 {
319 const unsigned element_dimension(elem->getDimension());
320 if (element_dimension < mesh_dimension)
321 {
322 continue;
323 }
324
325 if (element_dimension == 2)
326 {
327 if (!complete_surface)
328 {
329 if (MeshLib::FaceRule::getSurfaceNormal(*elem).normalized().dot(
330 norm_dir) > cos_theta)
331 {
332 continue;
333 }
334 }
335 sfc_elements.push_back(elem->clone());
336 element_to_bulk_element_id_map.push_back(elem->getID());
337 element_to_bulk_face_id_map.push_back(0);
338 }
339 else
340 {
341 if (!elem->isBoundaryElement())
342 {
343 continue;
344 }
345 const unsigned nFaces(elem->getNumberOfFaces());
346 for (unsigned j = 0; j < nFaces; ++j)
347 {
348 if (elem->getNeighbor(j) != nullptr)
349 {
350 continue;
351 }
352
353 auto const face =
354 std::unique_ptr<MeshLib::Element const>{elem->getFace(j)};
355 if (!complete_surface)
356 {
358 .normalized()
359 .dot(norm_dir) < cos_theta)
360 {
361 continue;
362 }
363 }
364 switch (face->getCellType())
365 {
367 sfc_elements.push_back(new MeshLib::Tri(
368 *static_cast<const MeshLib::Tri*>(face.get())));
369 break;
371 sfc_elements.push_back(new MeshLib::Tri6(
372 *static_cast<const MeshLib::Tri6*>(face.get())));
373 break;
375 sfc_elements.push_back(new MeshLib::Quad(
376 *static_cast<const MeshLib::Quad*>(face.get())));
377 break;
379 sfc_elements.push_back(new MeshLib::Quad8(
380 *static_cast<const MeshLib::Quad8*>(face.get())));
381 break;
383 sfc_elements.push_back(new MeshLib::Quad9(
384 *static_cast<const MeshLib::Quad9*>(face.get())));
385 break;
386 default:
387 DBUG("unknown cell type");
388 }
389 element_to_bulk_element_id_map.push_back(elem->getID());
390 element_to_bulk_face_id_map.push_back(j);
391 }
392 }
393 }
394}
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
static Eigen::Vector3d getSurfaceNormal(Element const &e)
Returns the surface normal of a 2D element.
Definition FaceRule.cpp:40

References DBUG(), ERR(), MeshLib::FaceRule::getSurfaceNormal(), MeshLib::QUAD4, MeshLib::QUAD8, MeshLib::QUAD9, MeshLib::TRI3, and MeshLib::TRI6.

Referenced by getMeshSurface(), and getSurfaceNodes().

◆ getMeshSurface()

MeshLib::Mesh * MeshToolsLib::MeshSurfaceExtraction::getMeshSurface ( const MeshLib::Mesh & subsfc_mesh,
Eigen::Vector3d const & dir,
double angle,
std::string_view subsfc_node_id_prop_name = "",
std::string_view subsfc_element_id_prop_name = "",
std::string_view 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 244 of file MeshSurfaceExtraction.cpp.

249{
250 // allow slightly greater angles than 90 degrees for numerical errors
251 if (angle < 0 || angle > 91)
252 {
253 ERR("Supported angle between 0 and 90 degrees only.");
254 return nullptr;
255 }
256
257 INFO("Extracting mesh surface...");
258 std::vector<MeshLib::Element*> sfc_elements;
259 std::vector<std::size_t> element_ids_map;
260 std::vector<std::size_t> face_ids_map;
261 get2DSurfaceElements(subsfc_mesh.getElements(), sfc_elements,
262 element_ids_map, face_ids_map, dir, angle,
263 subsfc_mesh.getDimension());
264
265 if (sfc_elements.empty())
266 {
267 return nullptr;
268 }
269
270 auto [sfc_nodes, node_id_map] = createNodesAndIDMapFromElements(
271 sfc_elements, subsfc_mesh.getNumberOfNodes());
272
273 // create new elements vector with newly created nodes (and delete
274 // temp-elements)
275 auto new_elements =
276 MeshLib::copyElementVector(sfc_elements, sfc_nodes, &node_id_map);
277 std::for_each(sfc_elements.begin(), sfc_elements.end(),
278 [](MeshLib::Element* e) { delete e; });
279
280 auto sfc_node_ids = sfc_nodes | MeshLib::views::ids;
281 std::vector<std::size_t> const id_map(sfc_node_ids.begin(),
282 sfc_node_ids.end());
283
284 MeshLib::Mesh* result(
285 new MeshLib::Mesh(subsfc_mesh.getName() + "-Surface", sfc_nodes,
286 new_elements, true /* compute_element_neighbors */));
287
288 addBulkIDPropertiesToMesh(*result, subsfc_node_id_prop_name, id_map,
289 subsfc_element_id_prop_name, element_ids_map,
290 face_id_prop_name, face_ids_map);
291
292 if (!createSfcMeshProperties(*result, subsfc_mesh.getProperties(), id_map,
293 element_ids_map))
294 {
295 ERR("Transferring subsurface properties failed.");
296 }
297 return result;
298}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:109
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:88
Properties & getProperties()
Definition Mesh.h:134
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:103
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:100
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()
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
Definition Mesh.h:225
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)
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)
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)
void addBulkIDPropertiesToMesh(MeshLib::Mesh &surface_mesh, std::string_view node_to_bulk_node_id_map_name, std::vector< std::size_t > const &node_to_bulk_node_id_map, std::string_view element_to_bulk_element_id_map_name, std::vector< std::size_t > const &element_to_bulk_element_id_map, std::string_view element_to_bulk_face_id_map_name, std::vector< std::size_t > const &element_to_bulk_face_id_map)

References MeshToolsLib::addBulkIDPropertiesToMesh(), MeshLib::copyElementVector(), MeshToolsLib::createNodesAndIDMapFromElements(), MeshToolsLib::createSfcMeshProperties(), ERR(), get2DSurfaceElements(), MeshLib::Mesh::getDimension(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getName(), MeshLib::Mesh::getNumberOfNodes(), MeshLib::Mesh::getProperties(), MeshLib::views::ids, and INFO().

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

◆ getSurfaceAreaForNodes()

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

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

Definition at line 202 of file MeshSurfaceExtraction.cpp.

204{
205 std::vector<double> node_area_vec;
206 if (mesh.getDimension() != 2)
207 {
208 ERR("Error in MeshSurfaceExtraction::getSurfaceAreaForNodes() - Given "
209 "mesh is no surface mesh (dimension != 2).");
210 return node_area_vec;
211 }
212
213 double total_area(0);
214
215 // for each node, a vector containing all the element idget every element
216 const std::vector<MeshLib::Node*>& nodes = mesh.getNodes();
217 const std::size_t nNodes(mesh.getNumberOfNodes());
218 for (std::size_t n = 0; n < nNodes; ++n)
219 {
220 double node_area(0);
221
222 auto const conn_elems = mesh.getElementsConnectedToNode(*nodes[n]);
223 const std::size_t nConnElems(conn_elems.size());
224
225 for (std::size_t i = 0; i < nConnElems; ++i)
226 {
227 const MeshLib::Element* elem(conn_elems[i]);
228 const unsigned nElemParts =
229 (elem->getGeomType() == MeshLib::MeshElemType::TRIANGLE) ? 3
230 : 4;
231 const double area = conn_elems[i]->getContent() / nElemParts;
232 node_area += area;
233 total_area += area;
234 }
235
236 node_area_vec.push_back(node_area);
237 }
238
239 INFO("Total surface Area: {:f}", total_area);
240
241 return node_area_vec;
242}
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:106
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
Definition Mesh.cpp:256

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 * > MeshToolsLib::MeshSurfaceExtraction::getSurfaceNodes ( const MeshLib::Mesh & mesh,
Eigen::Vector3d const & dir,
double angle )
static

Returns the surface nodes of a mesh.

Definition at line 396 of file MeshSurfaceExtraction.cpp.

398{
399 INFO("Extracting surface nodes...");
400 std::vector<MeshLib::Element*> sfc_elements;
401 std::vector<std::size_t> element_to_bulk_element_id_map;
402 std::vector<std::size_t> element_to_bulk_face_id_map;
403
405 mesh.getElements(), sfc_elements, element_to_bulk_element_id_map,
406 element_to_bulk_face_id_map, dir, angle, mesh.getDimension());
407
408 std::vector<MeshLib::Node*> surface_nodes;
409 std::tie(surface_nodes, std::ignore) =
411
412 for (auto e : sfc_elements)
413 {
414 delete e;
415 }
416
417 return surface_nodes;
418}

References MeshToolsLib::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: