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;
67 bool const compute_element_neighbors,
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),
76 _compute_element_neighbors(compute_element_neighbors)
92 _mesh_dimension(mesh.getDimension()),
93 _node_distance(mesh._node_distance.first, mesh._node_distance.second),
95 _nodes(mesh.getNumberOfNodes()),
96 _elements(mesh.getNumberOfElements()),
97 _properties(mesh._properties),
98 _compute_element_neighbors(mesh._compute_element_neighbors)
100 const std::vector<Node*>& nodes(mesh.
getNodes());
101 const std::size_t nNodes(nodes.size());
102 for (
unsigned i = 0; i < nNodes; ++i)
107 const std::vector<Element*>& elements(mesh.
getElements());
108 const std::size_t nElements(elements.size());
109 for (
unsigned i = 0; i < nElements; ++i)
112 for (
auto const& [j, node_id] :
113 elements[i]->nodes() |
views::ids | ranges::views::enumerate)
141 const std::size_t nElements(
_elements.size());
142 for (std::size_t i = 0; i < nElements; ++i)
147 const std::size_t nNodes(
_nodes.size());
148 for (std::size_t i = 0; i < nNodes; ++i)
161 const std::size_t nNodes(
_nodes.size());
162 for (std::size_t i = 0; i < nNodes; ++i)
170 const std::size_t nElements(this->
_elements.size());
171 for (
unsigned i = 0; i < nElements; ++i)
179 const std::size_t nElements(
_elements.size());
180 for (
unsigned i = 0; i < nElements; ++i)
190 std::vector<Element*>
const& elements)
192 auto min_max = [](
auto const a,
auto const b) -> std::pair<double, double> {
193 return {std::min(a.first, b.first), std::max(a.second, b.second)};
196 using limits = std::numeric_limits<double>;
197 auto const bounds = ranges::accumulate(
198 elements, std::pair{limits::infinity(), -limits::infinity()}, min_max,
201 return {std::sqrt(bounds.first), std::sqrt(bounds.second)};
206 std::vector<Element const*> neighbors;
211 const std::size_t nNodes(element->getNumberOfBaseNodes());
212 for (
unsigned n(0); n < nNodes; ++n)
214 auto const& conn_elems(
216 neighbors.insert(neighbors.end(), conn_elems.begin(),
219 std::sort(neighbors.begin(), neighbors.end());
220 auto const neighbors_new_end =
221 std::unique(neighbors.begin(), neighbors.end());
223 for (
auto neighbor = neighbors.begin(); neighbor != neighbors_new_end;
226 std::optional<unsigned>
const opposite_face_id =
227 element->addNeighbor(
const_cast<Element*
>(*neighbor));
228 if (opposite_face_id)
241 [
this](
auto const*
const node) {
257 std::size_t
const node_id)
const
263 Node const& node)
const
271 if (properties.existsPropertyVector<
int>(
"MaterialIDs",
274 return properties.getPropertyVector<
int>(
277 if (properties.hasPropertyVector(
"MaterialIDs"))
280 "The 'MaterialIDs' mesh property exists but is either of wrong "
281 "type (must be int), or it is not defined on element / cell data.");
313 std::vector<std::vector<Node*>> nodes_connected_by_elements;
314 auto const& nodes = mesh.
getNodes();
315 nodes_connected_by_elements.resize(nodes.size());
316 for (std::size_t i = 0; i < nodes.size(); ++i)
318 auto& adjacent_nodes = nodes_connected_by_elements[i];
319 auto const node_id = nodes[i]->getID();
322 auto const& connected_elements = elements_connected_to_nodes[node_id];
325 for (
Element const*
const element : connected_elements)
327 Node*
const*
const single_elem_nodes = element->getNodes();
328 std::size_t
const nnodes = element->getNumberOfNodes();
329 for (std::size_t n = 0; n < nnodes; n++)
331 adjacent_nodes.push_back(single_elem_nodes[n]);
337 std::sort(adjacent_nodes.begin(), adjacent_nodes.end(),
340 std::unique(adjacent_nodes.begin(), adjacent_nodes.end());
341 adjacent_nodes.erase(last, adjacent_nodes.end());
343 return nodes_connected_by_elements;
347 std::vector<Element const*>
const& elements_connected_to_node)
350 if (elements_connected_to_node.empty())
356 auto const e = elements_connected_to_node[0];
358 auto const n_base_nodes = e->getNumberOfBaseNodes();
360 return local_index < n_base_nodes;
364 std::string_view
const name)
368 [&name](
auto const& mesh)
370 assert(mesh !=
nullptr);
371 return mesh->getName() == name;
373 [&]() {
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)