OGS
createLayeredMeshFromRasters.cpp File Reference
#include <tclap/CmdLine.h>
#include <algorithm>
#include <iterator>
#include <memory>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/view/join.hpp>
#include <range/v3/view/repeat_n.hpp>
#include <string>
#include <vector>
#include "BaseLib/FileTools.h"
#include "BaseLib/IO/readStringListFromFile.h"
#include "BaseLib/MPI.h"
#include "GeoLib/IO/AsciiRasterInterface.h"
#include "InfoLib/GitInfo.h"
#include "MeshLib/IO/VtkIO/VtuInterface.h"
#include "MeshLib/IO/readMeshFromFile.h"
#include "MeshLib/Mesh.h"
#include "MeshToolsLib/MeshGenerators/MeshLayerMapper.h"
Include dependency graph for createLayeredMeshFromRasters.cpp:

Go to the source code of this file.

Functions

void assignSurfaceMaterialIDsToSubsurfaceLayers (MeshLib::Mesh *sfc_mesh, MeshLib::Mesh *subsurface_mesh)
 
int main (int argc, char *argv[])
 

Function Documentation

◆ assignSurfaceMaterialIDsToSubsurfaceLayers()

void assignSurfaceMaterialIDsToSubsurfaceLayers ( MeshLib::Mesh * sfc_mesh,
MeshLib::Mesh * subsurface_mesh )

Definition at line 34 of file createLayeredMeshFromRasters.cpp.

36{
37 auto const* surface_material_ids = materialIDs(*sfc_mesh);
38 auto* subsurface_material_ids = materialIDs(*subsurface_mesh);
39 // reset the material ids
40 if (!surface_material_ids)
41 {
42 OGS_FATAL("Surface mesh does not contain material IDs");
43 }
44 if (surface_material_ids->empty())
45 {
46 OGS_FATAL("Surface mesh material IDs doesn't contain any values");
47 }
48 if (!subsurface_material_ids)
49 {
50 OGS_FATAL("Subsurface mesh does not contain material IDs");
51 }
52 if (subsurface_material_ids->size() % surface_material_ids->size() != 0)
53 {
54 OGS_FATAL("Could not determine the number of subsurface layers.");
55 }
56 int const number_of_layers =
57 subsurface_material_ids->size() / surface_material_ids->size();
58
59 ranges::copy(
60 ranges::views::repeat_n(*surface_material_ids, number_of_layers) |
61 ranges::views::join,
62 subsurface_material_ids->begin());
63}
#define OGS_FATAL(...)
Definition Error.h:26
PropertyVector< int > const * materialIDs(Mesh const &mesh)
Definition Mesh.cpp:269

References OGS_FATAL.

Referenced by main().

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 65 of file createLayeredMeshFromRasters.cpp.

66{
67 TCLAP::CmdLine cmd(
68 "Creates a layered 3D OGS mesh from an existing 2D OGS mesh and a list "
69 "of raster files representing subsurface layers. Supported raster "
70 "formats are ArcGIS ascii rasters (*.asc), Surfer Grids (*.grd), or "
71 "gridded XYZ rasters (*.xyz)."
72 "Only input meshes consisting of line and triangle elements are "
73 "currently supported as mapping of quads might result in invalid mesh "
74 "elements.\n\n"
75 "OpenGeoSys-6 software, version " +
77 ".\n"
78 "Copyright (c) 2012-2025, OpenGeoSys Community "
79 "(http://www.opengeosys.org)",
81
82 TCLAP::SwitchArg use_ascii_arg("", "ascii_output",
83 "Write VTU output in ASCII format.");
84 cmd.add(use_ascii_arg);
85
86 double min_thickness(std::numeric_limits<double>::epsilon());
87 TCLAP::ValueArg<double> min_thickness_arg(
88 "t", "thickness",
89 "The minimum thickness of a layer to be integrated at any given "
90 "location, (min = 0)",
91 false, min_thickness, "MIN_THICKNESS");
92 cmd.add(min_thickness_arg);
93
94 TCLAP::ValueArg<std::string> raster_path_arg(
95 "r", "raster-list",
96 "Input (.vtu). An ascii-file containing a list of input "
97 "raster files, starting from"
98 "top (DEM) to bottom",
99 true, "", "INPUT_FILE_LIST");
100 cmd.add(raster_path_arg);
101
102 TCLAP::SwitchArg keep_materials_arg(
103 "", "keep-surface-material-ids",
104 "if the argument is present the materials defined in the surface mesh "
105 "are used to set the material information for the subsurface cells",
106 false);
107 cmd.add(keep_materials_arg);
108
109 TCLAP::ValueArg<std::string> mesh_out_arg(
110 "o", "output-mesh-file",
111 "Output (.vtu). The file name of the resulting 3D mesh", true, "",
112 "OUTPUT_FILE");
113 cmd.add(mesh_out_arg);
114
115 TCLAP::ValueArg<std::string> mesh_arg(
116 "i", "input-mesh-file",
117 "Input (.vtu). The file name of the 2D input mesh", true, "",
118 "INPUT_FILE");
119 cmd.add(mesh_arg);
120
121 cmd.parse(argc, argv);
122
123 BaseLib::MPI::Setup mpi_setup(argc, argv);
124
125 if (min_thickness_arg.isSet())
126 {
127 min_thickness = min_thickness_arg.getValue();
128 if (min_thickness < 0)
129 {
130 ERR("Minimum layer thickness must be non-negative value.");
131 return EXIT_FAILURE;
132 }
133 }
134
135 INFO("Reading mesh '{:s}' ... ", mesh_arg.getValue());
136 std::unique_ptr<MeshLib::Mesh> const sfc_mesh(
137 MeshLib::IO::readMeshFromFile(mesh_arg.getValue()));
138 if (!sfc_mesh)
139 {
140 ERR("Error reading mesh '{:s}'.", mesh_arg.getValue());
141 return EXIT_FAILURE;
142 }
143 if (sfc_mesh->getDimension() != 2)
144 {
145 ERR("Input mesh must be a 2D mesh.");
146 return EXIT_FAILURE;
147 }
148 INFO("done.");
149
150 std::vector<std::string> raster_paths =
151 BaseLib::IO::readStringListFromFile(raster_path_arg.getValue());
152 if (raster_paths.size() < 2)
153 {
154 ERR("At least two raster files needed to create 3D mesh.");
155 return EXIT_FAILURE;
156 }
157 std::reverse(raster_paths.begin(), raster_paths.end());
158
160 if (auto const rasters = FileIO::readRasters(raster_paths))
161 {
162 if (!mapper.createLayers(*sfc_mesh, *rasters, min_thickness))
163 {
164 return EXIT_FAILURE;
165 }
166 }
167 else
168 {
169 ERR("Reading raster files.");
170 return EXIT_FAILURE;
171 }
172
173 auto const result_mesh = mapper.getMesh("SubsurfaceMesh");
174 if (result_mesh == nullptr)
175 {
176 ERR("Mapper returned empty result for 'SubsurfaceMesh'.");
177 return EXIT_FAILURE;
178 }
179
180 if (keep_materials_arg.getValue())
181 {
183 result_mesh.get());
184 }
185
186 std::string output_name(mesh_out_arg.getValue());
187 if (!BaseLib::hasFileExtension(".vtu", output_name))
188 {
189 output_name.append(".vtu");
190 }
191
192 INFO("Writing mesh '{:s}' ... ", output_name);
193 auto const data_mode =
194 use_ascii_arg.getValue() ? vtkXMLWriter::Ascii : vtkXMLWriter::Binary;
195
196 MeshLib::IO::writeVtu(*result_mesh, output_name, data_mode);
197 INFO("done.");
198
199 return EXIT_SUCCESS;
200}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
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::Mesh > getMesh(std::string const &mesh_name) const
Returns a mesh of the subsurface representation.
Manipulating and adding prism element layers to an existing 2D mesh.
void assignSurfaceMaterialIDsToSubsurfaceLayers(MeshLib::Mesh *sfc_mesh, MeshLib::Mesh *subsurface_mesh)
std::vector< std::string > readStringListFromFile(std::string const &filename)
Reads non-empty lines from a list of strings from a file into a vector.
bool hasFileExtension(std::string const &extension, std::string const &filename)
std::optional< std::vector< GeoLib::Raster const * > > readRasters(std::vector< std::string > const &raster_paths)
GITINFOLIB_EXPORT const std::string ogs_version
int writeVtu(MeshLib::Mesh const &mesh, std::string const &file_name, int const data_mode)
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)

References assignSurfaceMaterialIDsToSubsurfaceLayers(), LayeredMeshGenerator::createLayers(), ERR(), LayeredMeshGenerator::getMesh(), BaseLib::hasFileExtension(), INFO(), GitInfoLib::GitInfo::ogs_version, MeshLib::IO::readMeshFromFile(), FileIO::readRasters(), BaseLib::IO::readStringListFromFile(), and MeshLib::IO::writeVtu().