OGS
MeshToolsLib::MeshSurfaceExtraction Class Reference

Detailed Description

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

Definition at line 27 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 293 of file MeshSurfaceExtraction.cpp.

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

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 237 of file MeshSurfaceExtraction.cpp.

242{
243 // allow slightly greater angles than 90 degrees for numerical errors
244 if (angle < 0 || angle > 91)
245 {
246 ERR("Supported angle between 0 and 90 degrees only.");
247 return nullptr;
248 }
249
250 INFO("Extracting mesh surface...");
251 std::vector<MeshLib::Element*> sfc_elements;
252 std::vector<std::size_t> element_ids_map;
253 std::vector<std::size_t> face_ids_map;
254 get2DSurfaceElements(subsfc_mesh.getElements(), sfc_elements,
255 element_ids_map, face_ids_map, dir, angle,
256 subsfc_mesh.getDimension());
257
258 if (sfc_elements.empty())
259 {
260 return nullptr;
261 }
262
263 auto [sfc_nodes, node_id_map] = createNodesAndIDMapFromElements(
264 sfc_elements, subsfc_mesh.getNumberOfNodes());
265
266 // create new elements vector with newly created nodes (and delete
267 // temp-elements)
268 auto new_elements =
269 MeshLib::copyElementVector(sfc_elements, sfc_nodes, &node_id_map);
270 std::for_each(sfc_elements.begin(), sfc_elements.end(),
271 [](MeshLib::Element* e) { delete e; });
272
273 auto sfc_node_ids = sfc_nodes | MeshLib::views::ids;
274 std::vector<std::size_t> const id_map(sfc_node_ids.begin(),
275 sfc_node_ids.end());
276
277 MeshLib::Mesh* result(
278 new MeshLib::Mesh(subsfc_mesh.getName() + "-Surface", sfc_nodes,
279 new_elements, true /* compute_element_neighbors */));
280
281 addBulkIDPropertiesToMesh(*result, subsfc_node_id_prop_name, id_map,
282 subsfc_element_id_prop_name, element_ids_map,
283 face_id_prop_name, face_ids_map);
284
285 if (!createSfcMeshProperties(*result, subsfc_mesh.getProperties(), id_map,
286 element_ids_map))
287 {
288 ERR("Transferring subsurface properties failed.");
289 }
290 return result;
291}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:100
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:79
Properties & getProperties()
Definition Mesh.h:125
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:94
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:91
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:216
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 195 of file MeshSurfaceExtraction.cpp.

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

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 389 of file MeshSurfaceExtraction.cpp.

391{
392 INFO("Extracting surface nodes...");
393 std::vector<MeshLib::Element*> sfc_elements;
394 std::vector<std::size_t> element_to_bulk_element_id_map;
395 std::vector<std::size_t> element_to_bulk_face_id_map;
396
398 mesh.getElements(), sfc_elements, element_to_bulk_element_id_map,
399 element_to_bulk_face_id_map, dir, angle, mesh.getDimension());
400
401 std::vector<MeshLib::Node*> surface_nodes;
402 std::tie(surface_nodes, std::ignore) =
404
405 for (auto e : sfc_elements)
406 {
407 delete e;
408 }
409
410 return surface_nodes;
411}

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: