18#include <range/v3/numeric.hpp>
19#include <range/v3/range/conversion.hpp>
20#include <range/v3/view/enumerate.hpp>
21#include <range/v3/view/indirect.hpp>
22#include <range/v3/view/map.hpp>
23#include <unordered_map>
44using namespace ranges;
49 std::vector<std::vector<Element const*>> elements_connected_to_nodes;
51 elements_connected_to_nodes.resize(nodes.size());
55 for (
auto const node_id : element->nodes() |
views::ids)
57 elements_connected_to_nodes[node_id].push_back(element);
60 return elements_connected_to_nodes;
71 _node_distance(std::numeric_limits<double>::max(), 0),
72 _name(std::move(name)),
73 _nodes(std::move(nodes)),
74 _elements(std::move(elements)),
75 _properties(properties)
88 _mesh_dimension(mesh.getDimension()),
89 _node_distance(mesh._node_distance.first, mesh._node_distance.second),
91 _nodes(mesh.getNumberOfNodes()),
92 _elements(mesh.getNumberOfElements()),
93 _properties(mesh._properties)
95 const std::vector<Node*>& nodes(mesh.
getNodes());
96 const std::size_t nNodes(nodes.size());
97 for (
unsigned i = 0; i < nNodes; ++i)
102 const std::vector<Element*>& elements(mesh.
getElements());
103 const std::size_t nElements(elements.size());
104 for (
unsigned i = 0; i < nElements; ++i)
107 for (
auto const& [j, node_id] :
108 elements[i]->nodes() |
views::ids | ranges::views::enumerate)
132 const std::size_t nElements(
_elements.size());
133 for (std::size_t i = 0; i < nElements; ++i)
138 const std::size_t nNodes(
_nodes.size());
139 for (std::size_t i = 0; i < nNodes; ++i)
152 const std::size_t nNodes(
_nodes.size());
153 for (std::size_t i = 0; i < nNodes; ++i)
161 const std::size_t nElements(this->
_elements.size());
162 for (
unsigned i = 0; i < nElements; ++i)
170 const std::size_t nElements(
_elements.size());
171 for (
unsigned i = 0; i < nElements; ++i)
181 std::vector<Element*>
const& elements)
183 auto min_max = [](
auto const a,
auto const b) -> std::pair<double, double> {
184 return {std::min(a.first, b.first), std::max(a.second, b.second)};
187 using limits = std::numeric_limits<double>;
188 auto const bounds = ranges::accumulate(
189 elements, std::pair{limits::infinity(), -limits::infinity()}, min_max,
192 return {std::sqrt(bounds.first), std::sqrt(bounds.second)};
197 std::vector<Element const*> neighbors;
202 const std::size_t nNodes(element->getNumberOfBaseNodes());
203 for (
unsigned n(0); n < nNodes; ++n)
205 auto const& conn_elems(
207 neighbors.insert(neighbors.end(), conn_elems.begin(),
210 std::sort(neighbors.begin(), neighbors.end());
211 auto const neighbors_new_end =
212 std::unique(neighbors.begin(), neighbors.end());
214 for (
auto neighbor = neighbors.begin(); neighbor != neighbors_new_end;
217 std::optional<unsigned>
const opposite_face_id =
218 element->addNeighbor(
const_cast<Element*
>(*neighbor));
219 if (opposite_face_id)
232 [
this](
auto const*
const node) {
248 std::size_t
const node_id)
const
254 Node const& node)
const
260 std::string
const& property_name,
265 WARN(
"Did not find PropertyVector '{:s}' for scaling.", property_name);
269 std::transform(pv.begin(), pv.end(), pv.begin(),
270 [factor](
auto const& v) { return v * factor; });
276 if (properties.existsPropertyVector<
int>(
"MaterialIDs",
282 if (properties.hasPropertyVector(
"MaterialIDs"))
285 "The 'MaterialIDs' mesh property exists but is either of wrong "
286 "type (must be int), or it is not defined on element / cell data.");
292 std::string mesh_name, std::vector<MeshLib::Element*>
const& elements)
294 auto ids_vector =
views::ids | to<std::vector>();
296 DBUG(
"Found {:d} elements in the mesh", elements.size());
299 auto bulk_element_ids = elements | ids_vector;
302 std::unordered_map<std::size_t, MeshLib::Node*> id_node_hash_map;
303 id_node_hash_map.reserve(
306 for (
auto& e : elements)
309 unsigned const n_nodes = e->getNumberOfNodes();
310 for (
unsigned i = 0; i < n_nodes; ++i)
313 auto const it = id_node_hash_map.find(n->
getID());
314 if (it == id_node_hash_map.end())
316 auto new_node_in_map = id_node_hash_map[n->
getID()] =
318 e->setNode(i, new_node_in_map);
322 e->setNode(i, it->second);
327 std::map<std::size_t, MeshLib::Node*> nodes_map;
328 for (
const auto& n : id_node_hash_map)
330 nodes_map[n.first] = n.second;
334 auto element_nodes = nodes_map | ranges::views::values | to<std::vector>;
337 auto bulk_node_ids = nodes_map | ranges::views::keys | to<std::vector>;
339 auto mesh = std::make_unique<MeshLib::Mesh>(
340 std::move(mesh_name), std::move(element_nodes), std::move(elements));
341 assert(mesh !=
nullptr);
349 return std::make_unique<MeshLib::NodePartitionedMesh>(*mesh);
360 std::vector<std::vector<Node*>> nodes_connected_by_elements;
361 auto const& nodes = mesh.
getNodes();
362 nodes_connected_by_elements.resize(nodes.size());
363 for (std::size_t i = 0; i < nodes.size(); ++i)
365 auto& adjacent_nodes = nodes_connected_by_elements[i];
366 auto const node_id = nodes[i]->getID();
369 auto const& connected_elements = elements_connected_to_nodes[node_id];
372 for (
Element const*
const element : connected_elements)
374 Node*
const*
const single_elem_nodes = element->getNodes();
375 std::size_t
const nnodes = element->getNumberOfNodes();
376 for (std::size_t n = 0; n < nnodes; n++)
378 adjacent_nodes.push_back(single_elem_nodes[n]);
384 std::sort(adjacent_nodes.begin(), adjacent_nodes.end(),
385 [](
Node* a,
Node* b) { return a->getID() < b->getID(); });
387 std::unique(adjacent_nodes.begin(), adjacent_nodes.end());
388 adjacent_nodes.erase(last, adjacent_nodes.end());
390 return nodes_connected_by_elements;
394 std::vector<Element const*>
const& elements_connected_to_node)
397 if (elements_connected_to_node.empty())
403 auto const e = elements_connected_to_node[0];
405 auto const n_base_nodes = e->getNumberOfBaseNodes();
407 return local_index < n_base_nodes;
Definition of the Element class.
Definition of the Hex class.
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
static std::size_t global_mesh_counter
Mesh counter used to uniquely identify meshes by id.
Definition of the Mesh class.
Definition of mesh class for partitioned mesh (by node) for parallel computing within the framework o...
Definition of the Prism class.
Definition of the Pyramid class.
Definition of the Quad class.
Definition of the RunTime class.
Definition of the Tet class.
Definition of the Tri class.
std::size_t getID() const
void setNeighbor(Element *neighbor, unsigned const face_id)
virtual unsigned getNumberOfNodes() const =0
virtual unsigned getNumberOfBaseNodes() const =0
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
std::vector< std::vector< Element const * > > _elements_connected_to_nodes
Mesh(std::string name, std::vector< Node * > nodes, std::vector< Element * > elements, Properties const &properties=Properties())
void addElement(Element *elem)
Add an element to the mesh.
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
std::size_t computeNumberOfBaseNodes() const
Get the number of base nodes.
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
void resetNodeIDs()
Resets the IDs of all mesh-nodes to their position in the node vector.
Properties & getProperties()
std::vector< Element * > _elements
void setDimension()
Sets the dimension of the mesh.
void resetElementIDs()
Resets the IDs of all mesh-elements to their position in the element vector.
void setElementNeighbors()
virtual ~Mesh()
Destructor.
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
bool hasNonlinearElement() const
Check if the mesh contains any nonlinear element.
std::vector< Node * > _nodes
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
bool existsPropertyVector(std::string_view name) const
PropertyVector< T > const * getPropertyVector(std::string_view name) const
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
std::vector< std::vector< Element const * > > findElementsConnectedToNodes(Mesh const &mesh)
std::unique_ptr< MeshLib::Mesh > createMeshFromElementSelection(std::string mesh_name, std::vector< MeshLib::Element * > const &elements)
std::vector< std::vector< Node * > > calculateNodesConnectedByElements(Mesh const &mesh)
PropertyVector< int > const * materialIDs(Mesh const &mesh)
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)
std::pair< double, double > computeSqrEdgeLengthRange(Element const &element)
Compute the minimum and maximum squared edge length for this element.
std::pair< double, double > minMaxEdgeLength(std::vector< Element * > const &elements)
Returns the minimum and maximum edge length for given elements.
unsigned getNodeIDinElement(Element const &element, const MeshLib::Node *node)
Returns the position of the given node in the node array of this element.
bool isBaseNode(Node const &node, std::vector< Element const * > const &elements_connected_to_node)
void scaleMeshPropertyVector(MeshLib::Mesh &mesh, std::string const &property_name, double factor)
void addPropertyToMesh(Mesh &mesh, std::string_view name, MeshItemType item_type, std::size_t number_of_components, std::vector< T > const &values)