18#include <range/v3/algorithm/contains.hpp>
19#include <range/v3/numeric.hpp>
20#include <range/v3/range/conversion.hpp>
21#include <range/v3/view/enumerate.hpp>
22#include <range/v3/view/indirect.hpp>
23#include <range/v3/view/map.hpp>
24#include <unordered_map>
43using namespace ranges;
48 std::vector<std::vector<Element const*>> elements_connected_to_nodes;
50 elements_connected_to_nodes.resize(nodes.size());
54 for (
auto const node_id : element->nodes() |
views::ids)
56 elements_connected_to_nodes[node_id].push_back(element);
59 return elements_connected_to_nodes;
70 _node_distance(std::numeric_limits<double>::max(), 0),
71 _name(std::move(name)),
72 _nodes(std::move(nodes)),
73 _elements(std::move(elements)),
74 _properties(properties)
87 _mesh_dimension(mesh.getDimension()),
88 _node_distance(mesh._node_distance.first, mesh._node_distance.second),
90 _nodes(mesh.getNumberOfNodes()),
91 _elements(mesh.getNumberOfElements()),
92 _properties(mesh._properties)
94 const std::vector<Node*>& nodes(mesh.
getNodes());
95 const std::size_t nNodes(nodes.size());
96 for (
unsigned i = 0; i < nNodes; ++i)
101 const std::vector<Element*>& elements(mesh.
getElements());
102 const std::size_t nElements(elements.size());
103 for (
unsigned i = 0; i < nElements; ++i)
106 for (
auto const& [j, node_id] :
107 elements[i]->nodes() |
views::ids | ranges::views::enumerate)
131 const std::size_t nElements(
_elements.size());
132 for (std::size_t i = 0; i < nElements; ++i)
137 const std::size_t nNodes(
_nodes.size());
138 for (std::size_t i = 0; i < nNodes; ++i)
151 const std::size_t nNodes(
_nodes.size());
152 for (std::size_t i = 0; i < nNodes; ++i)
160 const std::size_t nElements(this->
_elements.size());
161 for (
unsigned i = 0; i < nElements; ++i)
169 const std::size_t nElements(
_elements.size());
170 for (
unsigned i = 0; i < nElements; ++i)
180 std::vector<Element*>
const& elements)
182 auto min_max = [](
auto const a,
auto const b) -> std::pair<double, double> {
183 return {std::min(a.first, b.first), std::max(a.second, b.second)};
186 using limits = std::numeric_limits<double>;
187 auto const bounds = ranges::accumulate(
188 elements, std::pair{limits::infinity(), -limits::infinity()}, min_max,
191 return {std::sqrt(bounds.first), std::sqrt(bounds.second)};
196 std::vector<Element const*> neighbors;
201 const std::size_t nNodes(element->getNumberOfBaseNodes());
202 for (
unsigned n(0); n < nNodes; ++n)
204 auto const& conn_elems(
206 neighbors.insert(neighbors.end(), conn_elems.begin(),
209 std::sort(neighbors.begin(), neighbors.end());
210 auto const neighbors_new_end =
211 std::unique(neighbors.begin(), neighbors.end());
213 for (
auto neighbor = neighbors.begin(); neighbor != neighbors_new_end;
216 std::optional<unsigned>
const opposite_face_id =
217 element->addNeighbor(
const_cast<Element*
>(*neighbor));
218 if (opposite_face_id)
231 [
this](
auto const*
const node) {
247 std::size_t
const node_id)
const
253 Node const& node)
const
261 if (properties.existsPropertyVector<
int>(
"MaterialIDs",
267 if (properties.hasPropertyVector(
"MaterialIDs"))
270 "The 'MaterialIDs' mesh property exists but is either of wrong "
271 "type (must be int), or it is not defined on element / cell data.");
303 std::vector<std::vector<Node*>> nodes_connected_by_elements;
304 auto const& nodes = mesh.
getNodes();
305 nodes_connected_by_elements.resize(nodes.size());
306 for (std::size_t i = 0; i < nodes.size(); ++i)
308 auto& adjacent_nodes = nodes_connected_by_elements[i];
309 auto const node_id = nodes[i]->getID();
312 auto const& connected_elements = elements_connected_to_nodes[node_id];
315 for (
Element const*
const element : connected_elements)
317 Node*
const*
const single_elem_nodes = element->getNodes();
318 std::size_t
const nnodes = element->getNumberOfNodes();
319 for (std::size_t n = 0; n < nnodes; n++)
321 adjacent_nodes.push_back(single_elem_nodes[n]);
327 std::sort(adjacent_nodes.begin(), adjacent_nodes.end(),
328 idsComparator<Node*>);
330 std::unique(adjacent_nodes.begin(), adjacent_nodes.end());
331 adjacent_nodes.erase(last, adjacent_nodes.end());
333 return nodes_connected_by_elements;
337 std::vector<Element const*>
const& elements_connected_to_node)
340 if (elements_connected_to_node.empty())
346 auto const e = elements_connected_to_node[0];
348 auto const n_base_nodes = e->getNumberOfBaseNodes();
350 return local_index < n_base_nodes;
Definition of Duplicate functions.
Definition of the Element class.
Definition of the Hex class.
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 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....
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::vector< std::vector< Node * > > calculateNodesConnectedByElements(Mesh const &mesh)
PropertyVector< int > const * materialIDs(Mesh const &mesh)
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)
PropertyVector< std::size_t > const * bulkElementIDs(Mesh const &mesh)
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)
PropertyVector< std::size_t > const * bulkNodeIDs(Mesh const &mesh)