32 MeshLib::Mesh const& mesh, std::vector<float>
const& layer_thickness_vector,
33 std::string
const& mesh_name)
35 std::vector<float> thickness;
36 for (std::size_t i = 0; i < layer_thickness_vector.size(); ++i)
38 if (layer_thickness_vector[i] > std::numeric_limits<float>::epsilon())
40 thickness.push_back(layer_thickness_vector[i]);
44 WARN(
"Ignoring layer {:d} with thickness {:f}.", i,
45 layer_thickness_vector[i]);
49 const std::size_t nLayers(thickness.size());
52 ERR(
"MeshLayerMapper::createStaticLayers(): A 2D mesh with nLayers > 0 "
53 "is required as input.");
59 const std::size_t nElems(
62 { return (elem->getDimension() == 2); }));
65 const std::vector<MeshLib::Node*>& nodes = mesh.
getNodes();
66 const std::vector<MeshLib::Element*>& elems = mesh.
getElements();
67 std::vector<MeshLib::Node*> new_nodes(nNodes + (nLayers * nNodes));
68 std::vector<MeshLib::Element*> new_elems;
69 new_elems.reserve(nElems * nLayers);
75 ERR(
"Could not create PropertyVector object 'MaterialIDs'.");
79 materials->reserve(nElems * nLayers);
82 for (
unsigned layer_id = 0; layer_id <= nLayers; ++layer_id)
85 unsigned node_offset(nNodes * layer_id);
88 z_offset += thickness[layer_id - 1];
91 std::transform(nodes.cbegin(), nodes.cend(),
92 new_nodes.begin() + node_offset,
94 return new MeshLib::Node((*node)[0], (*node)[1],
95 (*node)[2] - z_offset);
105 node_offset -= nNodes;
106 const unsigned mat_id(nLayers - layer_id);
108 for (
unsigned i = 0; i < nOrgElems; ++i)
119 for (
unsigned j = 0; j < nElemNodes; ++j)
121 const unsigned node_id =
123 e_nodes[j] = new_nodes[node_id + nNodes];
124 e_nodes[j + nElemNodes] = new_nodes[node_id];
138 OGS_FATAL(
"MeshLayerMapper: Unknown element type to extrude.");
140 materials->push_back(mat_id);
149 std::vector<GeoLib::Raster const*>
const& rasters,
150 double minimum_thickness,
151 double noDataReplacementValue)
153 const std::size_t nLayers(rasters.size());
156 ERR(
"MeshLayerMapper::createRasterLayers(): A 2D mesh and at least two "
157 "rasters required as input.");
161 auto top = std::make_unique<MeshLib::Mesh>(mesh);
162 if (!
layerMapping(*top, *rasters.back(), noDataReplacementValue))
167 auto bottom = std::make_unique<MeshLib::Mesh>(mesh);
175 _nodes.reserve(nLayers * nNodes);
178 std::size_t
const nElems(std::count_if(
181 { return (elem->getGeomType() == MeshLib::MeshElemType::TRIANGLE); }));
182 _elements.reserve(nElems * (nLayers - 1));
186 std::vector<MeshLib::Node*>
const& nodes = bottom->getNodes();
187 std::transform(nodes.begin(), nodes.end(), std::back_inserter(
_nodes),
188 [](
auto const* node) { return new MeshLib::Node(*node); });
191 for (std::size_t i = 0; i < nLayers - 1; ++i)
203 const unsigned pyramid_base[3][4] = {
210 std::vector<MeshLib::Node*>
const& top_nodes = dem_mesh.
getNodes();
211 int const last_layer_node_offset = layer_id * nNodes;
214 for (std::size_t i = 0; i < nNodes; ++i)
217 *
_nodes[last_layer_node_offset + i],
221 std::vector<MeshLib::Element*>
const& elems = dem_mesh.
getElements();
224 for (std::size_t i = 0; i < nElems; ++i)
231 unsigned node_counter(3);
232 unsigned missing_idx(0);
233 std::array<MeshLib::Node*, 6> new_elem_nodes{};
234 for (
unsigned j = 0; j < 3; ++j)
237 _nodes[
_nodes[last_layer_node_offset + getNodeIndex(*elem, j)]
239 new_elem_nodes[node_counter] =
240 (
_nodes[last_layer_node_offset + getNodeIndex(*elem, j) +
242 if (new_elem_nodes[j]->getID() !=
243 new_elem_nodes[node_counter]->getID())
253 switch (node_counter)
261 std::array<MeshLib::Node*, 5> pyramid_nodes{};
262 pyramid_nodes[0] = new_elem_nodes[pyramid_base[missing_idx][0]];
263 pyramid_nodes[1] = new_elem_nodes[pyramid_base[missing_idx][1]];
264 pyramid_nodes[2] = new_elem_nodes[pyramid_base[missing_idx][2]];
265 pyramid_nodes[3] = new_elem_nodes[pyramid_base[missing_idx][3]];
266 pyramid_nodes[4] = new_elem_nodes[missing_idx];
273 std::array<MeshLib::Node*, 4> tet_nodes{};
274 std::copy(new_elem_nodes.begin(),
275 new_elem_nodes.begin() + node_counter,
289 double const nodata_replacement,
290 bool const ignore_nodata)
294 ERR(
"MshLayerMapper::layerMapping() - requires 2D mesh");
299 const double x0(header.
origin[0]);
300 const double y0(header.
origin[1]);
303 const std::pair<double, double> xDim(
304 x0, x0 + header.
n_cols * delta);
305 const std::pair<double, double> yDim(
306 y0, y0 + header.
n_rows * delta);
309 const std::vector<MeshLib::Node*>& nodes = mesh.
getNodes();
310 for (
unsigned i = 0; i < nNodes; ++i)
315 (*nodes[i])[2] = nodata_replacement;
320 constexpr double eps = std::numeric_limits<double>::epsilon();
321 if (std::abs(elevation - header.
no_data) < eps)
327 elevation = nodata_replacement;
333 (*nodes[i])[2] = elevation;
344 ERR(
"MshLayerMapper::mapToStaticValue() - requires 2D mesh");
348 std::vector<MeshLib::Node*>
const& nodes(mesh.
getNodes());
Definition of the Hex class.
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition of the MeshLayerMapper class.
Definition of the class Properties that implements a container of properties.
Definition of the Prism class.
Definition of the Pyramid class.
Definition of the GeoLib::Raster class.
Definition of the Tet class.
Class Raster is used for managing raster data.
double getValueAtPoint(const MathLib::Point3d &pnt) const
bool isPntOnRaster(MathLib::Point3d const &pnt) const
double interpolateValueAtPoint(const MathLib::Point3d &pnt) const
RasterHeader const & getHeader() const
Returns the complete header information.
double _minimum_thickness
std::vector< int > _materials
MeshLib::Node * getNewLayerNode(MeshLib::Node const &dem_node, MeshLib::Node const &last_layer_node, GeoLib::Raster const &raster, std::size_t new_node_id) const
std::vector< MeshLib::Node * > _nodes
std::vector< MeshLib::Element * > _elements
std::size_t getID() const
virtual MeshElemType getGeomType() const =0
virtual unsigned getNumberOfBaseNodes() const =0
virtual const Node * getNode(unsigned idx) const =0
virtual constexpr unsigned getDimension() const =0
Get dimension of the mesh element.
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
std::size_t getNumberOfNodes() const
Get the number of nodes.
std::size_t getNumberOfElements() const
Get the number of elements.
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)