18#include <range/v3/algorithm/contains.hpp>
19#include <range/v3/numeric.hpp>
20#include <range/v3/numeric/accumulate.hpp>
21#include <range/v3/range/conversion.hpp>
22#include <range/v3/view/enumerate.hpp>
23#include <range/v3/view/indirect.hpp>
24#include <range/v3/view/map.hpp>
25#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;
68 bool const compute_element_neighbors,
72 _node_distance(std::numeric_limits<double>::max(), 0),
73 _name(std::move(name)),
74 _nodes(std::move(nodes)),
75 _elements(std::move(elements)),
76 _properties(properties),
77 _compute_element_neighbors(compute_element_neighbors)
93 _mesh_dimension(mesh.getDimension()),
94 _node_distance(mesh._node_distance.first, mesh._node_distance.second),
96 _nodes(mesh.getNumberOfNodes()),
97 _elements(mesh.getNumberOfElements()),
98 _properties(mesh._properties),
99 _compute_element_neighbors(mesh._compute_element_neighbors)
101 const std::vector<Node*>& nodes(mesh.
getNodes());
102 const std::size_t nNodes(nodes.size());
103 for (
unsigned i = 0; i < nNodes; ++i)
108 const std::vector<Element*>& elements(mesh.
getElements());
109 const std::size_t nElements(elements.size());
110 for (
unsigned i = 0; i < nElements; ++i)
113 for (
auto const& [j, node_id] :
114 elements[i]->nodes() |
views::ids | ranges::views::enumerate)
142 const std::size_t nElements(
_elements.size());
143 for (std::size_t i = 0; i < nElements; ++i)
148 const std::size_t nNodes(
_nodes.size());
149 for (std::size_t i = 0; i < nNodes; ++i)
162 const std::size_t nNodes(
_nodes.size());
163 for (std::size_t i = 0; i < nNodes; ++i)
171 const std::size_t nElements(this->
_elements.size());
172 for (
unsigned i = 0; i < nElements; ++i)
180 const std::size_t nElements(
_elements.size());
181 for (
unsigned i = 0; i < nElements; ++i)
191 std::vector<Element*>
const& elements)
193 auto min_max = [](
auto const a,
auto const b) -> std::pair<double, double> {
194 return {std::min(a.first, b.first), std::max(a.second, b.second)};
197 using limits = std::numeric_limits<double>;
198 auto const bounds = ranges::accumulate(
199 elements, std::pair{limits::infinity(), -limits::infinity()}, min_max,
202 return {std::sqrt(bounds.first), std::sqrt(bounds.second)};
207 std::vector<Element const*> neighbors;
212 const std::size_t nNodes(element->getNumberOfBaseNodes());
213 for (
unsigned n(0); n < nNodes; ++n)
215 auto const& conn_elems(
217 neighbors.insert(neighbors.end(), conn_elems.begin(),
220 std::sort(neighbors.begin(), neighbors.end());
221 auto const neighbors_new_end =
222 std::unique(neighbors.begin(), neighbors.end());
224 for (
auto neighbor = neighbors.begin(); neighbor != neighbors_new_end;
227 std::optional<unsigned>
const opposite_face_id =
228 element->addNeighbor(
const_cast<Element*
>(*neighbor));
229 if (opposite_face_id)
242 [
this](
auto const*
const node) {
258 std::size_t
const node_id)
const
264 Node const& node)
const
272 if (properties.existsPropertyVector<
int>(
"MaterialIDs",
275 return properties.getPropertyVector<
int>(
278 if (properties.hasPropertyVector(
"MaterialIDs"))
281 "The 'MaterialIDs' mesh property exists but is either of wrong "
282 "type (must be int), or it is not defined on element / cell data.");
314 std::vector<std::vector<Node*>> nodes_connected_by_elements;
315 auto const& nodes = mesh.
getNodes();
316 nodes_connected_by_elements.resize(nodes.size());
317 for (std::size_t i = 0; i < nodes.size(); ++i)
319 auto& adjacent_nodes = nodes_connected_by_elements[i];
320 auto const node_id = nodes[i]->getID();
323 auto const& connected_elements = elements_connected_to_nodes[node_id];
326 for (
Element const*
const element : connected_elements)
328 Node*
const*
const single_elem_nodes = element->getNodes();
329 std::size_t
const nnodes = element->getNumberOfNodes();
330 for (std::size_t n = 0; n < nnodes; n++)
332 adjacent_nodes.push_back(single_elem_nodes[n]);
338 std::sort(adjacent_nodes.begin(), adjacent_nodes.end(),
341 std::unique(adjacent_nodes.begin(), adjacent_nodes.end());
342 adjacent_nodes.erase(last, adjacent_nodes.end());
344 return nodes_connected_by_elements;
348 std::vector<Element const*>
const& elements_connected_to_node)
351 if (elements_connected_to_node.empty())
357 auto const e = elements_connected_to_node[0];
359 auto const n_base_nodes = e->getNumberOfBaseNodes();
361 assert(local_index <= e->getNumberOfNodes());
362 return local_index < n_base_nodes;
366 std::string_view
const name)
370 [&name](
auto const& mesh)
372 assert(mesh !=
nullptr);
373 return mesh->getName() == name;
375 [&]() {
OGS_FATAL(
"Required mesh named {:s} not found.", name); });
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.
bool const _compute_element_neighbors
std::vector< std::vector< Element const * > > _elements_connected_to_nodes
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.
Mesh(std::string name, std::vector< Node * > nodes, std::vector< Element * > elements, bool const compute_element_neighbors=false, Properties const &properties=Properties())
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
ranges::range_reference_t< Range > findElementOrError(Range &range, std::predicate< ranges::range_reference_t< Range > > auto &&predicate, std::invocable auto error_callback)
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)
Mesh & findMeshByName(std::vector< std::unique_ptr< Mesh > > const &meshes, std::string_view const name)
bool idsComparator(T const a, T const b)
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)