17 #include <boost/math/constants/constants.hpp>
34 std::vector<std::size_t>
const& id_map,
37 auto const number_of_components =
property.getNumberOfGlobalComponents();
39 auto sfc_prop = getOrCreateMeshProperty<T>(
41 number_of_components);
43 sfc_prop->reserve(id_map.size());
45 for (
auto bulk_id : id_map)
48 number_of_components, back_inserter(*sfc_prop));
54 std::vector<std::size_t>
const& node_ids_map,
55 std::vector<std::size_t>
const& element_ids_map)
59 if (node_ids_map.size() != n_nodes)
61 ERR(
"createSfcMeshProperties() - Incorrect number of node IDs ({:d}) "
62 "compared to actual number of surface nodes ({:d}).",
63 node_ids_map.size(), n_nodes);
67 if (element_ids_map.size() != n_elems)
69 ERR(
"createSfcMeshProperties() - Incorrect number of element IDs "
70 "({:d}) compared to actual number of surface elements ({:d}).",
71 element_ids_map.size(), n_elems);
74 std::map<MeshLib::MeshItemType, std::vector<std::size_t>
const*>
const
78 std::size_t vectors_copied(0);
79 std::size_t vectors_skipped(0);
80 for (
auto [
name, property] : properties)
86 "Skipping property vector '{:s}' - not defined on cells or "
93 auto const& id_map = *id_maps.at(property->getMeshItemType());
149 "Skipping property vector '{:s}' - no matching data type "
151 name,
typeid(*property).name());
155 INFO(
"{:d} property vectors copied, {:d} vectors skipped.", vectors_copied,
160 std::tuple<std::vector<MeshLib::Node*>, std::vector<std::size_t>>
162 std::size_t
const n_all_nodes)
164 std::vector<MeshLib::Node const*> tmp_nodes(n_all_nodes,
nullptr);
165 for (
auto const* elem : elements)
167 auto const n_nodes = elem->getNumberOfNodes();
168 for (
unsigned j = 0; j < n_nodes; ++j)
171 tmp_nodes[node->
getID()] = node;
175 std::vector<MeshLib::Node*> nodes;
176 std::vector<std::size_t> node_id_map(n_all_nodes);
177 for (
unsigned i = 0; i < n_all_nodes; ++i)
181 node_id_map[i] = nodes.size();
185 return {nodes, node_id_map};
191 std::vector<double> node_area_vec;
194 ERR(
"Error in MeshSurfaceExtraction::getSurfaceAreaForNodes() - Given "
195 "mesh is no surface mesh (dimension != 2).");
196 return node_area_vec;
199 double total_area(0);
202 const std::vector<MeshLib::Node*>& nodes = mesh.
getNodes();
204 for (std::size_t n = 0; n < nNodes; ++n)
209 const std::size_t nConnElems(conn_elems.size());
211 for (std::size_t i = 0; i < nConnElems; ++i)
214 const unsigned nElemParts =
216 const double area = conn_elems[i]->getContent() / nElemParts;
221 node_area_vec.push_back(node_area);
224 INFO(
"Total surface Area: {:f}", total_area);
226 return node_area_vec;
230 const MeshLib::Mesh& subsfc_mesh, Eigen::Vector3d
const& dir,
double angle,
231 std::string
const& subsfc_node_id_prop_name,
232 std::string
const& subsfc_element_id_prop_name,
233 std::string
const& face_id_prop_name)
236 if (angle < 0 || angle > 91)
238 ERR(
"Supported angle between 0 and 90 degrees only.");
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;
247 element_ids_map, face_ids_map, dir, angle,
250 if (sfc_elements.empty())
262 std::for_each(sfc_elements.begin(), sfc_elements.end(),
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),
271 new Mesh(subsfc_mesh.
getName() +
"-Surface", sfc_nodes, new_elements));
274 subsfc_element_id_prop_name, element_ids_map,
275 face_id_prop_name, face_ids_map);
280 ERR(
"Transferring subsurface properties failed.");
286 const std::vector<MeshLib::Element*>& all_elements,
287 std::vector<MeshLib::Element*>& sfc_elements,
288 std::vector<std::size_t>& element_to_bulk_element_id_map,
289 std::vector<std::size_t>& element_to_bulk_face_id_map,
290 Eigen::Vector3d
const& dir,
double angle,
unsigned mesh_dimension)
292 if (mesh_dimension < 2 || mesh_dimension > 3)
294 ERR(
"Cannot handle meshes of dimension {:i}", mesh_dimension);
297 bool const complete_surface = (dir.dot(dir) == 0);
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());
303 for (
auto const* elem : all_elements)
305 const unsigned element_dimension(elem->getDimension());
306 if (element_dimension < mesh_dimension)
311 if (element_dimension == 2)
313 if (!complete_surface)
316 norm_dir) > cos_theta)
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);
327 if (!elem->isBoundaryElement())
331 const unsigned nFaces(elem->getNumberOfFaces());
332 for (
unsigned j = 0; j < nFaces; ++j)
334 if (elem->getNeighbor(j) !=
nullptr)
340 std::unique_ptr<MeshLib::Element const>{elem->getFace(j)};
341 if (!complete_surface)
344 norm_dir) < cos_theta)
359 element_to_bulk_element_id_map.push_back(elem->getID());
360 element_to_bulk_face_id_map.push_back(j);
367 const MeshLib::Mesh& mesh, Eigen::Vector3d
const& dir,
double angle)
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;
375 mesh.
getElements(), sfc_elements, element_to_bulk_element_id_map,
376 element_to_bulk_face_id_map, dir, angle, mesh.
getDimension());
378 std::vector<MeshLib::Node*> surface_nodes;
379 std::tie(surface_nodes, std::ignore) =
382 for (
auto e : sfc_elements)
387 return surface_nodes;
392 std::vector<MeshLib::Element*>& surface_elements,
393 std::vector<std::size_t>& element_to_bulk_element_id_map,
394 std::vector<std::size_t>& element_to_bulk_face_id_map)
397 for (
unsigned j = 0; j < n_faces; ++j)
404 surface_elements.push_back(
406 element_to_bulk_face_id_map.push_back(j);
407 element_to_bulk_element_id_map.push_back(surface_element.
getID());
411 std::tuple<std::vector<MeshLib::Element*>, std::vector<std::size_t>,
412 std::vector<std::size_t>>
415 std::vector<std::size_t> element_to_bulk_element_id_map;
416 std::vector<std::size_t> element_to_bulk_face_id_map;
417 std::vector<MeshLib::Element*> surface_elements;
419 auto const& bulk_elements = bulk_mesh.
getElements();
422 for (
auto const* elem : bulk_elements)
424 const unsigned element_dimension(elem->getDimension());
425 if (element_dimension < mesh_dimension)
430 if (!elem->isBoundaryElement())
435 element_to_bulk_element_id_map,
436 element_to_bulk_face_id_map);
438 return {surface_elements, element_to_bulk_element_id_map,
439 element_to_bulk_face_id_map};
442 namespace BoundaryExtraction
446 std::string
const& subsfc_node_id_prop_name,
447 std::string
const& subsfc_element_id_prop_name,
448 std::string
const& face_id_prop_name)
451 if (mesh_dimension < 2 || mesh_dimension > 3)
453 ERR(
"Cannot handle meshes of dimension {:i}", mesh_dimension);
457 auto [boundary_elements, element_to_bulk_element_id_map,
466 boundary_elements, boundary_nodes, &node_id_map);
467 for (
auto* e : boundary_elements)
472 std::vector<std::size_t> nodes_to_bulk_nodes_id_map;
473 nodes_to_bulk_nodes_id_map.reserve(boundary_nodes.size());
474 std::transform(begin(boundary_nodes), end(boundary_nodes),
475 std::back_inserter(nodes_to_bulk_nodes_id_map),
478 std::unique_ptr<MeshLib::Mesh> boundary_mesh(
new Mesh(
479 bulk_mesh.
getName() +
"-boundary", boundary_nodes, new_elements));
482 *boundary_mesh, subsfc_node_id_prop_name, nodes_to_bulk_nodes_id_map,
483 subsfc_element_id_prop_name, element_to_bulk_element_id_map,
484 face_id_prop_name, element_to_bulk_face_id_map);
488 nodes_to_bulk_nodes_id_map,
489 element_to_bulk_element_id_map))
491 ERR(
"Transferring subsurface properties failed.");
493 return boundary_mesh;
500 std::string
const& node_to_bulk_node_id_map_name,
501 std::vector<std::size_t>
const& node_to_bulk_node_id_map,
502 std::string
const& element_to_bulk_element_id_map_name,
503 std::vector<std::size_t>
const& element_to_bulk_element_id_map,
504 std::string
const& element_to_bulk_face_id_map_name,
505 std::vector<std::size_t>
const& element_to_bulk_face_id_map)
508 if (!node_to_bulk_node_id_map_name.empty())
512 node_to_bulk_node_id_map);
516 if (!element_to_bulk_element_id_map_name.empty())
519 surface_mesh, element_to_bulk_element_id_map_name,
524 if (!element_to_bulk_face_id_map_name.empty())
527 surface_mesh, element_to_bulk_face_id_map_name,
Definition of Duplicate functions.
Definition of the Line class.
void INFO(char const *fmt, Args const &... args)
void ERR(char const *fmt, Args const &... args)
void WARN(char const *fmt, Args const &... args)
Definition of the Mesh class.
Definition of the Quad class.
Definition of the Tri class.
std::size_t getID() const
virtual MeshElemType getGeomType() const =0
virtual const Element * getBoundary(unsigned i) const =0
virtual const Element * getNeighbor(unsigned i) const =0
Get the specified neighbor.
virtual unsigned getNumberOfBoundaries() const =0
virtual std::size_t getID() const final
Returns the ID of the element.
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.
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
const std::string getName() const
Get name of the mesh.
Properties & getProperties()
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....
std::string const & getPropertyName() const
MeshItemType getMeshItemType() const
PROP_VAL_TYPE & getComponent(std::size_t tuple_index, int component)
Returns the value for the given component stored in the given tuple.
void createSurfaceElementsFromElement(MeshLib::Element const &surface_element, std::vector< MeshLib::Element * > &surface_elements, std::vector< std::size_t > &element_to_bulk_element_id_map, std::vector< std::size_t > &element_to_bulk_face_id_map)
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 processPropertyVector(MeshLib::PropertyVector< T > const &property, std::vector< std::size_t > const &id_map, MeshLib::Mesh &sfc_mesh)
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)
void addPropertyToMesh(Mesh &mesh, std::string const &name, MeshItemType item_type, std::size_t number_of_components, std::vector< T > const &values)
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::Element * >, std::vector< std::size_t >, std::vector< std::size_t > > createBoundaryElements(MeshLib::Mesh const &bulk_mesh)