8#include <range/v3/view/join.hpp>
9#include <range/v3/view/transform.hpp>
29 std::vector<std::size_t>
const& id_map,
32 auto const number_of_components =
property.getNumberOfGlobalComponents();
36 number_of_components);
38 auto get_components = [&](std::size_t
const bulk_id)
41 number_of_components);
43 sfc_prop->assign(id_map | ranges::views::transform(get_components) |
49 std::vector<std::size_t>
const& node_ids_map,
50 std::vector<std::size_t>
const& element_ids_map)
54 if (node_ids_map.size() != n_nodes)
56 ERR(
"createSfcMeshProperties() - Incorrect number of node IDs ({:d}) "
57 "compared to actual number of surface nodes ({:d}).",
58 node_ids_map.size(), n_nodes);
62 if (element_ids_map.size() != n_elems)
64 ERR(
"createSfcMeshProperties() - Incorrect number of element IDs "
65 "({:d}) compared to actual number of surface elements ({:d}).",
66 element_ids_map.size(), n_elems);
69 std::map<MeshLib::MeshItemType, std::vector<std::size_t>
const*>
const
73 std::size_t vectors_copied(0);
74 std::size_t vectors_skipped(0);
75 for (
auto [name, property] : properties)
81 "Skipping property vector '{:s}' - not defined on cells or "
88 auto const& id_map = *id_maps.at(property->getMeshItemType());
95 else if (
auto const* p =
101 else if (
auto const* p =
107 else if (
auto const* p =
113 else if (
auto const* p =
119 else if (
auto const* p =
126 else if (
auto const* p =
133 else if (
auto const* p =
140 else if (
auto const* p =
147 else if (
auto const* p =
156 "Skipping property vector '{:s}' - no matching data type "
162 INFO(
"{:d} property vectors copied, {:d} vectors skipped.", vectors_copied,
167std::tuple<std::vector<MeshLib::Node*>, std::vector<std::size_t>>
169 std::size_t
const n_all_nodes)
171 std::vector<MeshLib::Node const*> tmp_nodes(n_all_nodes,
nullptr);
172 for (
auto const* elem : elements)
174 auto const n_nodes = elem->getNumberOfNodes();
175 for (
unsigned j = 0; j < n_nodes; ++j)
178 tmp_nodes[node->
getID()] = node;
182 std::vector<MeshLib::Node*> nodes;
183 std::vector<std::size_t> node_id_map(n_all_nodes);
184 for (
unsigned i = 0; i < n_all_nodes; ++i)
188 node_id_map[i] = nodes.size();
192 return {nodes, node_id_map};
198 std::vector<double> node_area_vec;
201 ERR(
"Error in MeshSurfaceExtraction::getSurfaceAreaForNodes() - Given "
202 "mesh is no surface mesh (dimension != 2).");
203 return node_area_vec;
206 double total_area(0);
209 const std::vector<MeshLib::Node*>& nodes = mesh.
getNodes();
211 for (std::size_t n = 0; n < nNodes; ++n)
216 const std::size_t nConnElems(conn_elems.size());
218 for (std::size_t i = 0; i < nConnElems; ++i)
221 const unsigned nElemParts =
224 const double area = conn_elems[i]->getContent() / nElemParts;
229 node_area_vec.push_back(node_area);
232 INFO(
"Total surface Area: {:f}", total_area);
234 return node_area_vec;
238 const MeshLib::Mesh& subsfc_mesh, Eigen::Vector3d
const& dir,
double angle,
239 std::string_view subsfc_node_id_prop_name,
240 std::string_view subsfc_element_id_prop_name,
241 std::string_view face_id_prop_name)
244 if (angle < 0 || angle > 91)
246 ERR(
"Supported angle between 0 and 90 degrees only.");
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;
255 element_ids_map, face_ids_map, dir, angle,
258 if (sfc_elements.empty())
270 std::for_each(sfc_elements.begin(), sfc_elements.end(),
274 std::vector<std::size_t>
const id_map(sfc_node_ids.begin(),
279 new_elements,
true ));
282 subsfc_element_id_prop_name, element_ids_map,
283 face_id_prop_name, face_ids_map);
288 ERR(
"Transferring subsurface properties failed.");
294 const std::vector<MeshLib::Element*>& all_elements,
295 std::vector<MeshLib::Element*>& sfc_elements,
296 std::vector<std::size_t>& element_to_bulk_element_id_map,
297 std::vector<std::size_t>& element_to_bulk_face_id_map,
298 Eigen::Vector3d
const& dir,
double angle,
unsigned mesh_dimension)
300 if (mesh_dimension < 2 || mesh_dimension > 3)
302 ERR(
"Cannot handle meshes of dimension {}", mesh_dimension);
305 bool const complete_surface = (dir.dot(dir) == 0);
307 double const cos_theta(std::cos(angle * std::numbers::pi / 180.0));
308 Eigen::Vector3d
const norm_dir(dir.normalized());
310 for (
auto const* elem : all_elements)
312 const unsigned element_dimension(elem->getDimension());
313 if (element_dimension < mesh_dimension)
318 if (element_dimension == 2)
320 if (!complete_surface)
323 norm_dir) > cos_theta)
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);
334 if (!elem->isBoundaryElement())
338 const unsigned nFaces(elem->getNumberOfFaces());
339 for (
unsigned j = 0; j < nFaces; ++j)
341 if (elem->getNeighbor(j) !=
nullptr)
347 std::unique_ptr<MeshLib::Element const>{elem->getFace(j)};
348 if (!complete_surface)
352 .dot(norm_dir) < cos_theta)
357 switch (face->getCellType())
380 DBUG(
"unknown cell type");
382 element_to_bulk_element_id_map.push_back(elem->getID());
383 element_to_bulk_face_id_map.push_back(j);
390 const MeshLib::Mesh& mesh, Eigen::Vector3d
const& dir,
double angle)
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;
398 mesh.
getElements(), sfc_elements, element_to_bulk_element_id_map,
399 element_to_bulk_face_id_map, dir, angle, mesh.
getDimension());
401 std::vector<MeshLib::Node*> surface_nodes;
402 std::tie(surface_nodes, std::ignore) =
405 for (
auto e : sfc_elements)
410 return surface_nodes;
415 std::vector<MeshLib::Element*>& surface_elements,
416 std::vector<std::size_t>& element_to_bulk_element_id_map,
417 std::vector<std::size_t>& element_to_bulk_face_id_map)
420 for (
unsigned j = 0; j < n_faces; ++j)
427 surface_elements.push_back(
429 element_to_bulk_face_id_map.push_back(j);
430 element_to_bulk_element_id_map.push_back(surface_element.
getID());
434std::tuple<std::vector<MeshLib::Element*>, std::vector<std::size_t>,
435 std::vector<std::size_t>>
438 std::vector<std::size_t> element_to_bulk_element_id_map;
439 std::vector<std::size_t> element_to_bulk_face_id_map;
440 std::vector<MeshLib::Element*> surface_elements;
442 auto const& bulk_elements = bulk_mesh.
getElements();
445 for (
auto const* elem : bulk_elements)
447 const unsigned element_dimension(elem->getDimension());
448 if (element_dimension < mesh_dimension)
453 if (!elem->isBoundaryElement())
458 element_to_bulk_element_id_map,
459 element_to_bulk_face_id_map);
461 return {surface_elements, element_to_bulk_element_id_map,
462 element_to_bulk_face_id_map};
469 std::string_view subsfc_node_id_prop_name,
470 std::string_view subsfc_element_id_prop_name,
471 std::string_view face_id_prop_name)
474 if (mesh_dimension < 2 || mesh_dimension > 3)
476 ERR(
"Cannot handle meshes of dimension {}", mesh_dimension);
480 auto [boundary_elements, element_to_bulk_element_id_map,
489 boundary_elements, boundary_nodes, &node_id_map);
490 for (
auto* e : boundary_elements)
497 std::vector<std::size_t>
const nodes_to_bulk_nodes_id_map(
498 boundary_node_ids.begin(), boundary_node_ids.end());
500 std::unique_ptr<MeshLib::Mesh> boundary_mesh(
502 new_elements,
true ));
505 *boundary_mesh, subsfc_node_id_prop_name, nodes_to_bulk_nodes_id_map,
506 subsfc_element_id_prop_name, element_to_bulk_element_id_map,
507 face_id_prop_name, element_to_bulk_face_id_map);
511 nodes_to_bulk_nodes_id_map,
512 element_to_bulk_element_id_map))
514 ERR(
"Transferring subsurface properties failed.");
516 return boundary_mesh;
523 std::string_view node_to_bulk_node_id_map_name,
524 std::vector<std::size_t>
const& node_to_bulk_node_id_map,
525 std::string_view element_to_bulk_element_id_map_name,
526 std::vector<std::size_t>
const& element_to_bulk_element_id_map,
527 std::string_view element_to_bulk_face_id_map_name,
528 std::vector<std::size_t>
const& element_to_bulk_face_id_map)
531 if (!node_to_bulk_node_id_map_name.empty())
534 surface_mesh, node_to_bulk_node_id_map_name,
539 if (!element_to_bulk_element_id_map_name.empty())
542 surface_mesh, element_to_bulk_element_id_map_name,
547 if (!element_to_bulk_face_id_map_name.empty())
550 surface_mesh, element_to_bulk_face_id_map_name,
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
std::size_t getID() const
virtual MeshElemType getGeomType() const =0
virtual unsigned getNumberOfBoundaries() const =0
std::size_t getID() const
Returns the ID of the element.
virtual const Element * getNeighbor(unsigned i) const =0
Get the specified neighbor.
virtual const Element * getBoundary(unsigned i) const =0
static Eigen::Vector3d getSurfaceNormal(Element const &e)
Returns the surface normal of a 2D element.
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Properties & getProperties()
const std::string getName() const
Get name of the mesh.
std::size_t getNumberOfNodes() const
Get the number of nodes.
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
std::size_t getNumberOfElements() const
Get the number of elements.
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
MeshItemType getMeshItemType() const
std::string const & getPropertyName() const
PROP_VAL_TYPE & getComponent(std::size_t tuple_index, int component)
Returns the value for the given component stored in the given tuple.
std::string typeToString()
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
TemplateElement< MeshLib::QuadRule9 > Quad9
PropertyVector< T > * getOrCreateMeshProperty(Mesh &mesh, std::string const &property_name, MeshItemType const item_type, int const number_of_components)
void addPropertyToMesh(Mesh &mesh, std::string_view name, MeshItemType item_type, std::size_t number_of_components, std::span< T const > values)
TemplateElement< MeshLib::QuadRule8 > Quad8
TemplateElement< MeshLib::QuadRule4 > Quad
TemplateElement< MeshLib::TriRule3 > Tri
TemplateElement< MeshLib::TriRule6 > Tri6
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)