OGS
Mesh2MeshPropertyInterpolation.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <fstream>
7#include <vector>
8
9#include "BaseLib/Logging.h"
10#include "GeoLib/AABB.h"
11#include "GeoLib/Grid.h"
13#include "MeshLib/Mesh.h"
14#include "MeshLib/MeshEnums.h"
15#include "MeshLib/Node.h"
16
17namespace MeshToolsLib
18{
20 MeshLib::Mesh const& src_mesh, std::string const& property_name)
21 : _src_mesh(src_mesh), _property_name(property_name)
22{
23}
24
26 MeshLib::Mesh& dest_mesh) const
27{
28 if (_src_mesh.getDimension() != dest_mesh.getDimension())
29 {
30 ERR("MeshLib::Mesh2MeshPropertyInterpolation::setPropertiesForMesh() "
31 "dimension of source (dim = {:d}) and destination (dim = {:d}) "
32 "mesh does not match.",
33 _src_mesh.getDimension(), dest_mesh.getDimension());
34 return false;
35 }
36
37 if (_src_mesh.getDimension() != 2)
38 {
39 WARN(
40 "MeshLib::Mesh2MeshPropertyInterpolation::setPropertiesForMesh() "
41 "implemented only for 2D case at the moment.");
42 return false;
43 }
44
45 MeshLib::PropertyVector<double>* dest_properties;
46 if (dest_mesh.getProperties().existsPropertyVector<double>(_property_name))
47 {
48 dest_properties =
50 assert(dest_properties->size() != dest_mesh.getNumberOfElements());
51 }
52 else
53 {
54 INFO("Create new PropertyVector '{:s}' of type double.",
56 dest_properties =
57 dest_mesh.getProperties().createNewPropertyVector<double>(
59 dest_mesh.getNumberOfElements(), 1);
60 if (!dest_properties)
61 {
62 WARN(
63 "Could not get or create a PropertyVector of type double using "
64 "the given name '{:s}'.",
66 return false;
67 }
68 }
69
70 interpolatePropertiesForMesh(dest_mesh, *dest_properties);
71
72 return true;
73}
74
76 MeshLib::Mesh const& dest_mesh,
77 MeshLib::PropertyVector<double>& dest_properties) const
78{
79 std::vector<double> interpolated_src_node_properties(
80 _src_mesh.getNumberOfNodes());
82 interpolated_src_node_properties);
83
84 // idea: looping over the destination elements and calculate properties
85 // from interpolated_src_node_properties to accelerate the (source) point
86 // search construct a grid
87 std::vector<MeshLib::Node*> const& src_nodes(_src_mesh.getNodes());
88 GeoLib::Grid<MeshLib::Node> src_grid(src_nodes.begin(), src_nodes.end(),
89 64);
90
91 auto const& dest_elements(dest_mesh.getElements());
92 const std::size_t n_dest_elements(dest_elements.size());
93 for (std::size_t k(0); k < n_dest_elements; k++)
94 {
95 MeshLib::Element& dest_element(*dest_elements[k]);
96 if (dest_element.getGeomType() == MeshLib::MeshElemType::LINE)
97 {
98 continue;
99 }
100
101 // compute axis aligned bounding box around the current element
102 const GeoLib::AABB elem_aabb(
103 dest_element.getNodes(),
104 dest_element.getNodes() + dest_element.getNumberOfBaseNodes());
105
106 // request "interesting" nodes from grid
107 std::vector<std::vector<MeshLib::Node*> const*> const nodes =
109 elem_aabb.getMinPoint(), elem_aabb.getMaxPoint());
110
111 std::size_t cnt(0);
112 double average_value(0.0);
113
114 for (auto const* nodes_vec : nodes)
115 {
116 for (auto const* node : *nodes_vec)
117 {
118 if (elem_aabb.containsPointXY(*node) &&
119 MeshLib::isPointInElementXY(*node, dest_element))
120 {
121 average_value +=
122 interpolated_src_node_properties[node->getID()];
123 cnt++;
124 }
125 }
126 }
127
128 if (cnt == 0)
129 {
130 OGS_FATAL(
131 "Mesh2MeshInterpolation: Could not find values in source mesh "
132 "for the element {:d}.",
133 k);
134 }
135 dest_properties[k] = average_value / cnt;
136 }
137}
138
141 std::vector<double>& interpolated_properties) const
142{
143 // fetch the source of property values
144 if (!_src_mesh.getProperties().existsPropertyVector<double>(_property_name))
145 {
146 WARN("Did not find PropertyVector<double> '{:s}'.", _property_name);
147 return;
148 }
149 auto const* elem_props =
150 _src_mesh.getProperties().getPropertyVector<double>(_property_name);
151
152 std::vector<MeshLib::Node*> const& src_nodes(_src_mesh.getNodes());
153 const std::size_t n_src_nodes(src_nodes.size());
154 for (std::size_t k(0); k < n_src_nodes; k++)
155 {
156 const std::size_t n_con_elems(
157 _src_mesh.getElementsConnectedToNode(*src_nodes[k]).size());
158 interpolated_properties[k] = (*elem_props)
159 [_src_mesh.getElementsConnectedToNode(*src_nodes[k])[0]->getID()];
160 for (std::size_t j(1); j < n_con_elems; j++)
161 {
162 interpolated_properties[k] +=
163 (*elem_props)[_src_mesh
164 .getElementsConnectedToNode(*src_nodes[k])[j]
165 ->getID()];
166 }
167 interpolated_properties[k] /= n_con_elems;
168 }
169}
170
171} // namespace MeshToolsLib
#define OGS_FATAL(...)
Definition Error.h:19
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition AABB.h:45
Eigen::Vector3d const & getMaxPoint() const
Definition AABB.h:176
Eigen::Vector3d const & getMinPoint() const
Definition AABB.h:169
bool containsPointXY(T const &pnt) const
Definition AABB.h:150
std::vector< std::vector< POINT * > const * > getPntVecsOfGridCellsIntersectingCuboid(Eigen::Vector3d const &min_pnt, Eigen::Vector3d const &max_pnt) const
Definition Grid.h:275
virtual MeshElemType getGeomType() const =0
virtual unsigned getNumberOfBaseNodes() const =0
virtual Node *const * getNodes() const =0
Get array of element nodes.
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:100
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:79
Properties & getProperties()
Definition Mesh.h:125
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:88
bool existsPropertyVector(std::string_view name) const
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)
PropertyVector< T > const * getPropertyVector(std::string_view name) const
constexpr std::size_t size() const
void interpolatePropertiesForMesh(MeshLib::Mesh const &dest_mesh, MeshLib::PropertyVector< double > &dest_properties) const
void interpolateElementPropertiesToNodeProperties(std::vector< double > &interpolated_properties) const
Mesh2MeshPropertyInterpolation(MeshLib::Mesh const &src_mesh, std::string const &property_name)
bool isPointInElementXY(MathLib::Point3d const &p, Element const &e)
Definition Element.cpp:178