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 pi(boost::math::constants::pi<double>());
315 double const cos_theta(std::cos(angle * pi / 180.0));
316 Eigen::Vector3d const norm_dir(dir.normalized());
317
318 for (auto const* elem : all_elements)
319 {
320 const unsigned element_dimension(elem->getDimension());
321 if (element_dimension < mesh_dimension)
322 {
323 continue;
324 }
325
326 if (element_dimension == 2)
327 {
328 if (!complete_surface)
329 {
330 if (MeshLib::FaceRule::getSurfaceNormal(*elem).normalized().dot(
331 norm_dir) > cos_theta)
332 {
333 continue;
334 }
335 }
336 sfc_elements.push_back(elem->clone());
337 element_to_bulk_element_id_map.push_back(elem->getID());
338 element_to_bulk_face_id_map.push_back(0);
339 }
340 else
341 {
342 if (!elem->isBoundaryElement())
343 {
344 continue;
345 }
346 const unsigned nFaces(elem->getNumberOfFaces());
347 for (unsigned j = 0; j < nFaces; ++j)
348 {
349 if (elem->getNeighbor(j) != nullptr)
350 {
351 continue;
352 }
353
354 auto const face =
355 std::unique_ptr<MeshLib::Element const>{elem->getFace(j)};
356 if (!complete_surface)
357 {
359 .normalized()
360 .dot(norm_dir) < cos_theta)
361 {
362 continue;
363 }
364 }
365 switch (face->getCellType())
366 {
368 sfc_elements.push_back(new MeshLib::Tri(
369 *static_cast<const MeshLib::Tri*>(face.get())));
370 break;
372 sfc_elements.push_back(new MeshLib::Tri6(
373 *static_cast<const MeshLib::Tri6*>(face.get())));
374 break;
376 sfc_elements.push_back(new MeshLib::Quad(
377 *static_cast<const MeshLib::Quad*>(face.get())));
378 break;
380 sfc_elements.push_back(new MeshLib::Quad8(
381 *static_cast<const MeshLib::Quad8*>(face.get())));
382 break;
384 sfc_elements.push_back(new MeshLib::Quad9(
385 *static_cast<const MeshLib::Quad9*>(face.get())));
386 break;
387 default:
388 DBUG("unknown cell type");
389 }
390 element_to_bulk_element_id_map.push_back(elem->getID());
391 element_to_bulk_face_id_map.push_back(j);
392 }
393 }
394 }
395}
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 397 of file MeshSurfaceExtraction.cpp.

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

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: