7#include <range/v3/algorithm/contains.hpp>
8#include <range/v3/numeric.hpp>
9#include <range/v3/numeric/accumulate.hpp>
10#include <range/v3/range/conversion.hpp>
11#include <range/v3/view/enumerate.hpp>
12#include <range/v3/view/indirect.hpp>
13#include <range/v3/view/map.hpp>
14#include <unordered_map>
33using namespace ranges;
43 std::vector<std::vector<Element const*>> elements_connected_to_nodes;
45 elements_connected_to_nodes.resize(nodes.size());
49 for (
auto const node_id : element->nodes() |
views::ids)
51 elements_connected_to_nodes[node_id].push_back(element);
54 return elements_connected_to_nodes;
62 bool const compute_element_neighbors,
65 _name(std::move(name)),
92 const std::vector<Node*>& nodes(mesh.
getNodes());
93 const std::size_t nNodes(nodes.size());
94 for (
unsigned i = 0; i < nNodes; ++i)
99 const std::vector<Element*>& elements(mesh.
getElements());
100 const std::size_t nElements(elements.size());
101 for (
unsigned i = 0; i < nElements; ++i)
104 for (
auto const& [j, node_id] :
105 elements[i]->nodes() |
views::ids | ranges::views::enumerate)
133 const std::size_t nElements(
_elements.size());
134 for (std::size_t i = 0; i < nElements; ++i)
139 const std::size_t nNodes(
_nodes.size());
140 for (std::size_t i = 0; i < nNodes; ++i)
153 const std::size_t nNodes(
_nodes.size());
154 for (std::size_t i = 0; i < nNodes; ++i)
162 const std::size_t nElements(this->
_elements.size());
163 for (
unsigned i = 0; i < nElements; ++i)
171 const std::size_t nElements(
_elements.size());
172 for (
unsigned i = 0; i < nElements; ++i)
182 std::vector<Element*>
const& elements)
184 auto min_max = [](
auto const a,
auto const b) -> std::pair<double, double> {
185 return {std::min(a.first, b.first), std::max(a.second, b.second)};
188 using limits = std::numeric_limits<double>;
189 auto const bounds = ranges::accumulate(
190 elements, std::pair{limits::infinity(), -limits::infinity()}, min_max,
193 return {std::sqrt(bounds.first), std::sqrt(bounds.second)};
198 std::vector<Element const*> neighbors;
203 const std::size_t nNodes(element->getNumberOfBaseNodes());
204 for (
unsigned n(0); n < nNodes; ++n)
206 auto const& conn_elems(
208 neighbors.insert(neighbors.end(), conn_elems.begin(),
211 std::sort(neighbors.begin(), neighbors.end());
212 auto const neighbors_new_end =
213 std::unique(neighbors.begin(), neighbors.end());
215 for (
auto neighbor = neighbors.begin(); neighbor != neighbors_new_end;
218 std::optional<unsigned>
const opposite_face_id =
219 element->addNeighbor(
const_cast<Element*
>(*neighbor));
220 if (opposite_face_id)
233 [
this](
auto const*
const node) {
249 std::size_t
const node_id)
const
255 Node const& node)
const
263 if (properties.existsPropertyVector<
int>(
"MaterialIDs",
266 return properties.getPropertyVector<
int>(
269 if (properties.hasPropertyVector(
"MaterialIDs"))
272 "The 'MaterialIDs' mesh property exists but is either of wrong "
273 "type (must be int), or it is not defined on element / cell data.");
305 std::vector<std::vector<Node*>> nodes_connected_by_elements;
306 auto const& nodes = mesh.
getNodes();
307 nodes_connected_by_elements.resize(nodes.size());
308 for (std::size_t i = 0; i < nodes.size(); ++i)
310 auto& adjacent_nodes = nodes_connected_by_elements[i];
311 auto const node_id = nodes[i]->getID();
314 auto const& connected_elements = elements_connected_to_nodes[node_id];
317 for (
Element const*
const element : connected_elements)
319 Node*
const*
const single_elem_nodes = element->getNodes();
320 std::size_t
const nnodes = element->getNumberOfNodes();
321 for (std::size_t n = 0; n < nnodes; n++)
323 adjacent_nodes.push_back(single_elem_nodes[n]);
329 std::sort(adjacent_nodes.begin(), adjacent_nodes.end(),
332 std::unique(adjacent_nodes.begin(), adjacent_nodes.end());
333 adjacent_nodes.erase(last, adjacent_nodes.end());
335 return nodes_connected_by_elements;
339 std::vector<Element const*>
const& elements_connected_to_node)
342 if (elements_connected_to_node.empty())
348 auto const e = elements_connected_to_node[0];
350 auto const n_base_nodes = e->getNumberOfBaseNodes();
352 assert(local_index <= e->getNumberOfNodes());
353 return local_index < n_base_nodes;
357 std::string_view
const name)
361 [&name](
auto const& mesh)
363 assert(mesh !=
nullptr);
364 return mesh->getName() == name;
366 [&]() {
OGS_FATAL(
"Required mesh named {:s} not found.", name); });
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.
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
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.
const std::string getName() const
Get name of the mesh.
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::size_t getNumberOfNodes() const
Get the number of nodes.
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
std::pair< double, double > _node_distance
bool hasNonlinearElement() const
Check if the mesh contains any nonlinear element.
static std::size_t nextID()
Returns the next unused mesh id from the global mesh counter.
std::size_t getNumberOfElements() const
Get the number of elements.
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)