OGS
LayeredVolume Class Reference

Detailed Description

Creates a volume geometry from 2D mesh layers based on raster data.

Definition at line 21 of file LayeredVolume.h.

#include <LayeredVolume.h>

Inheritance diagram for LayeredVolume:
[legend]
Collaboration diagram for LayeredVolume:
[legend]

Public Member Functions

 LayeredVolume ()=default
 ~LayeredVolume () override=default
bool createRasterLayers (const MeshLib::Mesh &mesh, const std::vector< GeoLib::Raster const * > &rasters, double minimum_thickness, double noDataReplacementValue=0.0) override
std::vector< MeshLib::NodegetAttributePoints () const
Public Member Functions inherited from LayeredMeshGenerator
virtual bool createLayers (MeshLib::Mesh const &mesh, std::vector< GeoLib::Raster const * > const &rasters, double minimum_thickness, double noDataReplacementValue=0.0) final
std::unique_ptr< MeshLib::MeshgetMesh (std::string const &mesh_name) const
 Returns a mesh of the subsurface representation.

Private Member Functions

void addLayerToMesh (const MeshLib::Mesh &dem_mesh, unsigned layer_id, GeoLib::Raster const &raster) override
 Adds another layer to the subsurface mesh.
void addLayerBoundaries (const MeshLib::Mesh &layer, std::size_t nLayers)
void removeCongruentElements (std::size_t nLayers, std::size_t nElementsPerLayer)
 Removes duplicate 2D elements (possible due to outcroppings)

Private Attributes

std::vector< MeshLib::Node_attribute_points

Additional Inherited Members

Protected Member Functions inherited from LayeredMeshGenerator
 LayeredMeshGenerator ()=default
virtual ~LayeredMeshGenerator ()=default
MeshLib::NodegetNewLayerNode (MeshLib::Node const &dem_node, MeshLib::Node const &last_layer_node, GeoLib::Raster const &raster, std::size_t new_node_id) const
Static Protected Member Functions inherited from LayeredMeshGenerator
static double calcEpsilon (GeoLib::Raster const &low, GeoLib::Raster const &high)
 Calculates a data-dependent epsilon value.
Protected Attributes inherited from LayeredMeshGenerator
double _elevation_epsilon {0.0001}
double _minimum_thickness {std::numeric_limits<float>::epsilon()}
std::vector< int > _materials
std::vector< MeshLib::Node * > _nodes
std::vector< MeshLib::Element * > _elements

Constructor & Destructor Documentation

◆ LayeredVolume()

LayeredVolume::LayeredVolume ( )
default

◆ ~LayeredVolume()

LayeredVolume::~LayeredVolume ( )
overridedefault

Member Function Documentation

◆ addLayerBoundaries()

void LayeredVolume::addLayerBoundaries ( const MeshLib::Mesh & layer,
std::size_t nLayers )
private

Creates boundary surfaces between the mapped layers to make the volumes watertight

Definition at line 122 of file LayeredVolume.cpp.

124{
125 const unsigned nLayerBoundaries(nLayers - 1);
126 const std::size_t nNodes(layer.getNumberOfNodes());
127 const std::vector<MeshLib::Element*>& layer_elements(layer.getElements());
128 for (MeshLib::Element* elem : layer_elements)
129 {
130 const std::size_t nElemNodes(elem->getNumberOfBaseNodes());
131 for (unsigned i = 0; i < nElemNodes; ++i)
132 {
133 if (elem->getNeighbor(i) == nullptr)
134 {
135 for (unsigned j = 0; j < nLayerBoundaries; ++j)
136 {
137 const std::size_t offset(j * nNodes);
138 MeshLib::Node* n0 = _nodes[offset + getNodeIndex(*elem, i)];
139 MeshLib::Node* n1 =
140 _nodes[offset +
141 getNodeIndex(*elem, (i + 1) % nElemNodes)];
142 MeshLib::Node* n2 =
143 _nodes[offset + nNodes +
144 getNodeIndex(*elem, (i + 1) % nElemNodes)];
145 MeshLib::Node* n3 =
146 _nodes[offset + nNodes + getNodeIndex(*elem, i)];
147
148 auto const& v0 = n0->asEigenVector3d();
149 auto const& v1 = n1->asEigenVector3d();
150 auto const& v2 = n2->asEigenVector3d();
151 auto const& v3 = n3->asEigenVector3d();
152 double const eps = std::numeric_limits<double>::epsilon();
153
154 if ((v2 - v1).norm() > eps)
155 {
156 const std::array tri_nodes = {n0, n2, n1};
157 _elements.push_back(new MeshLib::Tri(tri_nodes));
158 _materials.push_back(nLayers + j);
159 }
160 if ((v3 - v0).norm() > eps)
161 {
162 const std::array tri_nodes = {n0, n3, n2};
163 _elements.push_back(new MeshLib::Tri(tri_nodes));
164 _materials.push_back(nLayers + j);
165 }
166 }
167 }
168 }
169 }
170}
std::vector< int > _materials
std::vector< MeshLib::Node * > _nodes
std::vector< MeshLib::Element * > _elements
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:55
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:100
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:91
double norm(MatrixOrVector const &x, MathLib::VecNormType type)
Definition LinAlg.h:89
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition Element.cpp:226
TemplateElement< MeshLib::TriRule3 > Tri
Definition Tri.h:15

References LayeredMeshGenerator::_elements, LayeredMeshGenerator::_materials, LayeredMeshGenerator::_nodes, MathLib::Point3d::asEigenVector3d(), MeshLib::Mesh::getElements(), and MeshLib::Mesh::getNumberOfNodes().

Referenced by createRasterLayers().

◆ addLayerToMesh()

void LayeredVolume::addLayerToMesh ( const MeshLib::Mesh & dem_mesh,
unsigned layer_id,
GeoLib::Raster const & raster )
overrideprivatevirtual

Adds another layer to the subsurface mesh.

Implements LayeredMeshGenerator.

Definition at line 79 of file LayeredVolume.cpp.

82{
83 const std::size_t nNodes(dem_mesh.getNumberOfNodes());
84 const std::vector<MeshLib::Node*>& nodes(dem_mesh.getNodes());
85 const std::size_t node_id_offset(_nodes.size());
86 const std::size_t last_layer_node_offset(node_id_offset - nNodes);
87
88 for (std::size_t i = 0; i < nNodes; ++i)
89 {
90 _nodes.push_back(getNewLayerNode(*nodes[i],
91 *_nodes[last_layer_node_offset + i],
92 raster,
93 _nodes.size()));
94 }
95
96 const std::vector<MeshLib::Element*>& layer_elements(
97 dem_mesh.getElements());
98 for (MeshLib::Element* elem : layer_elements)
99 {
100 if (elem->getGeomType() == MeshLib::MeshElemType::TRIANGLE)
101 {
102 std::array<MeshLib::Node*, 3> tri_nodes = {
103 {_nodes[node_id_offset + getNodeIndex(*elem, 0)],
104 _nodes[node_id_offset + getNodeIndex(*elem, 1)],
105 _nodes[node_id_offset + getNodeIndex(*elem, 2)]}};
106 _elements.push_back(new MeshLib::Tri(tri_nodes));
107 _materials.push_back(layer_id);
108 }
109 else if (elem->getGeomType() == MeshLib::MeshElemType::QUAD)
110 {
111 std::array<MeshLib::Node*, 4> quad_nodes = {
112 {_nodes[node_id_offset + getNodeIndex(*elem, 0)],
113 _nodes[node_id_offset + getNodeIndex(*elem, 1)],
114 _nodes[node_id_offset + getNodeIndex(*elem, 2)],
115 _nodes[node_id_offset + getNodeIndex(*elem, 3)]}};
116 _elements.push_back(new MeshLib::Quad(quad_nodes));
117 _materials.push_back(layer_id);
118 }
119 }
120}
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< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:97
TemplateElement< MeshLib::QuadRule4 > Quad
Definition Quad.h:17

References LayeredMeshGenerator::_elements, LayeredMeshGenerator::_materials, LayeredMeshGenerator::_nodes, MeshLib::Mesh::getElements(), LayeredMeshGenerator::getNewLayerNode(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getNumberOfNodes(), MeshLib::QUAD, and MeshLib::TRIANGLE.

Referenced by createRasterLayers().

◆ createRasterLayers()

bool LayeredVolume::createRasterLayers ( const MeshLib::Mesh & mesh,
const std::vector< GeoLib::Raster const * > & rasters,
double minimum_thickness,
double noDataReplacementValue = 0.0 )
overridevirtual

Constructs a subsurface representation of a mesh using only 2D elements (i.e. layer boundaries are represented by surfaces)

Parameters
meshThe 2D surface mesh that is used as a basis for the subsurface mesh
rastersContaining all the raster-data for the subsurface layers from bottom to top (starting with the bottom of the oldest layer and ending with the DEM)
minimum_thicknessMinimum thickness of each of the newly created layers (i.e. nodes with a vertical distance smaller than this will be collapsed)
noDataReplacementValueDefault z-coordinate if there are mesh nodes not located on the DEM raster (i.e. raster_paths[0])
Returns
true if the subsurface representation has been created, false if there was an error

Implements LayeredMeshGenerator.

Definition at line 16 of file LayeredVolume.cpp.

21{
22 if (mesh.getDimension() != 2)
23 {
24 return false;
25 }
26
27 _elevation_epsilon = calcEpsilon(*rasters[0], *rasters.back());
28 if (_elevation_epsilon <= 0)
29 {
30 return false;
31 }
32
33 // remove line elements, only tri + quad remain
34 MeshLib::ElementSearch ex(mesh);
35 ex.searchByElementType(MeshLib::MeshElemType::LINE);
36 std::unique_ptr<MeshLib::Mesh> top(MeshToolsLib::removeElements(
37 mesh, ex.getSearchedElementIDs(), "MeshLayer"));
38 if (top == nullptr)
39 {
40 top = std::make_unique<MeshLib::Mesh>(mesh);
41 }
42
44 *top, *rasters.back(), noDataReplacementValue))
45 {
46 return false;
47 }
48
49 std::unique_ptr<MeshLib::Mesh> bottom(new MeshLib::Mesh(*top));
50 if (!MeshToolsLib::MeshLayerMapper::layerMapping(*bottom, *rasters[0], 0))
51 {
52 return false;
53 }
54
55 this->_minimum_thickness = minimum_thickness;
56 _nodes = MeshLib::copyNodeVector(bottom->getNodes());
57 _elements = MeshLib::copyElementVector(bottom->getElements(), _nodes);
58 if (!_materials.empty())
59 {
60 ERR("The materials vector is not empty.");
61 return false;
62 }
63 _materials.resize(_elements.size(), 0);
64
65 // map each layer and attach to subsurface mesh
66 const std::size_t nRasters(rasters.size());
67 for (std::size_t i = 1; i < nRasters; ++i)
68 {
69 this->addLayerToMesh(*top, i, *rasters[i]);
70 }
71
72 // close boundaries between layers
73 this->addLayerBoundaries(*top, nRasters);
74 this->removeCongruentElements(nRasters, top->getNumberOfElements());
75
76 return true;
77}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
static double calcEpsilon(GeoLib::Raster const &low, GeoLib::Raster const &high)
Calculates a data-dependent epsilon value.
void removeCongruentElements(std::size_t nLayers, std::size_t nElementsPerLayer)
Removes duplicate 2D elements (possible due to outcroppings)
void addLayerToMesh(const MeshLib::Mesh &dem_mesh, unsigned layer_id, GeoLib::Raster const &raster) override
Adds another layer to the subsurface mesh.
void addLayerBoundaries(const MeshLib::Mesh &layer, std::size_t nLayers)
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:79
static bool layerMapping(MeshLib::Mesh const &mesh, const GeoLib::Raster &raster, double nodata_replacement=0.0, bool const ignore_nodata=false)
std::vector< Node * > copyNodeVector(const std::vector< Node * > &nodes)
Creates a deep copy of a Node vector.
std::vector< Element * > copyElementVector(std::vector< Element * > const &elements, std::vector< Node * > const &new_nodes, std::vector< std::size_t > const *const node_id_map)
MeshLib::Mesh * removeElements(const MeshLib::Mesh &mesh, const std::vector< std::size_t > &removed_element_ids, const std::string &new_mesh_name)

References LayeredMeshGenerator::_elements, LayeredMeshGenerator::_elevation_epsilon, LayeredMeshGenerator::_materials, LayeredMeshGenerator::_minimum_thickness, LayeredMeshGenerator::_nodes, addLayerBoundaries(), addLayerToMesh(), LayeredMeshGenerator::calcEpsilon(), MeshLib::copyElementVector(), MeshLib::copyNodeVector(), ERR(), MeshLib::Mesh::getDimension(), MeshLib::ElementSearch::getSearchedElementIDs(), MeshToolsLib::MeshLayerMapper::layerMapping(), MeshLib::LINE, removeCongruentElements(), MeshToolsLib::removeElements(), and MeshLib::ElementSearch::searchByElementType().

◆ getAttributePoints()

std::vector< MeshLib::Node > LayeredVolume::getAttributePoints ( ) const
inline

Returns the region attribute vector necessary for assigning region attributes via TetGen

Definition at line 53 of file LayeredVolume.h.

54 {
55 return _attribute_points;
56 }
std::vector< MeshLib::Node > _attribute_points

References _attribute_points.

Referenced by MeshLayerEditDialog::createTetMesh(), and main().

◆ removeCongruentElements()

void LayeredVolume::removeCongruentElements ( std::size_t nLayers,
std::size_t nElementsPerLayer )
private

Removes duplicate 2D elements (possible due to outcroppings)

Definition at line 172 of file LayeredVolume.cpp.

174{
175 for (std::size_t i = nLayers - 1; i > 0; --i)
176 {
177 const std::size_t lower_offset((i - 1) * nElementsPerLayer);
178 const std::size_t upper_offset(i * nElementsPerLayer);
179 for (std::size_t j = 0; j < nElementsPerLayer; ++j)
180 {
181 MeshLib::Element const* const high(_elements[upper_offset + j]);
182 MeshLib::Element* const low(_elements[lower_offset + j]);
183
184 unsigned count(0);
185 const std::size_t nElemNodes(low->getNumberOfBaseNodes());
186 for (std::size_t k = 0; k < nElemNodes; ++k)
187 {
188 if (getNodeIndex(*high, k) == getNodeIndex(*low, k))
189 {
190 low->setNode(k, _nodes[getNodeIndex(*high, k)]);
191 count++;
192 }
193 }
194
195 if (count == nElemNodes)
196 {
197 delete _elements[upper_offset + j];
198 // mark element and material entries for deletion
199 _elements[upper_offset + j] = nullptr;
200 _materials[upper_offset + j] = -1;
201 }
202 else
203 {
204 auto const& attr = MeshLib::getCenterOfGravity(*high);
205 _attribute_points.emplace_back(
206 attr[0],
207 attr[1],
208 (attr[2] + MeshLib::getCenterOfGravity(*low)[2]) / 2.0,
209 _materials[lower_offset + j]);
210 }
211 }
212 }
213 // delete marked entries
214 auto elem_vec_end =
215 std::remove(_elements.begin(), _elements.end(), nullptr);
216 _elements.erase(elem_vec_end, _elements.end());
217 auto mat_vec_end = std::remove(_materials.begin(), _materials.end(), -1);
218 _materials.erase(mat_vec_end, _materials.end());
219}
MathLib::Point3d getCenterOfGravity(Element const &element)
Calculates the center of gravity for the mesh element.
Definition Element.cpp:131

References _attribute_points, LayeredMeshGenerator::_elements, LayeredMeshGenerator::_materials, LayeredMeshGenerator::_nodes, MeshLib::getCenterOfGravity(), MeshLib::Element::getNumberOfBaseNodes(), and MeshLib::Element::setNode().

Referenced by createRasterLayers().

Member Data Documentation

◆ _attribute_points

std::vector<MeshLib::Node> LayeredVolume::_attribute_points
private

Definition at line 72 of file LayeredVolume.h.

Referenced by getAttributePoints(), and removeCongruentElements().


The documentation for this class was generated from the following files: