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.",
91 false, min_thickness, "floating point number");
92 cmd.add(min_thickness_arg);
93
94 TCLAP::ValueArg<std::string> raster_path_arg(
95 "r", "raster-list",
96 "An ascii-file containing a list of raster files, starting from top "
97 "(DEM) to bottom.",
98 true, "", "file name");
99 cmd.add(raster_path_arg);
100
101 TCLAP::SwitchArg keep_materials_arg(
102 "", "keep-surface-material-ids",
103 "if the argument is present the materials defined in the surface mesh "
104 "are used to set the material information for the subsurface cells",
105 false);
106 cmd.add(keep_materials_arg);
107
108 TCLAP::ValueArg<std::string> mesh_out_arg(
109 "o", "output-mesh-file", "The file name of the resulting 3D mesh.",
110 true, "", "file name");
111 cmd.add(mesh_out_arg);
112
113 TCLAP::ValueArg<std::string> mesh_arg("i", "input-mesh-file",
114 "The file name of the 2D input mesh.",
115 true, "", "file name");
116 cmd.add(mesh_arg);
117
118 cmd.parse(argc, argv);
119
121
122 if (min_thickness_arg.isSet())
123 {
124 min_thickness = min_thickness_arg.getValue();
125 if (min_thickness < 0)
126 {
127 ERR(
"Minimum layer thickness must be non-negative value.");
128 return EXIT_FAILURE;
129 }
130 }
131
132 INFO(
"Reading mesh '{:s}' ... ", mesh_arg.getValue());
133 std::unique_ptr<MeshLib::Mesh> const sfc_mesh(
135 if (!sfc_mesh)
136 {
137 ERR(
"Error reading mesh '{:s}'.", mesh_arg.getValue());
138 return EXIT_FAILURE;
139 }
140 if (sfc_mesh->getDimension() != 2)
141 {
142 ERR(
"Input mesh must be a 2D mesh.");
143 return EXIT_FAILURE;
144 }
146
147 std::vector<std::string> raster_paths =
149 if (raster_paths.size() < 2)
150 {
151 ERR(
"At least two raster files needed to create 3D mesh.");
152 return EXIT_FAILURE;
153 }
154 std::reverse(raster_paths.begin(), raster_paths.end());
155
158 {
159 if (!mapper.
createLayers(*sfc_mesh, *rasters, min_thickness))
160 {
161 return EXIT_FAILURE;
162 }
163 }
164 else
165 {
166 ERR(
"Reading raster files.");
167 return EXIT_FAILURE;
168 }
169
170 auto const result_mesh = mapper.
getMesh(
"SubsurfaceMesh");
171 if (result_mesh == nullptr)
172 {
173 ERR(
"Mapper returned empty result for 'SubsurfaceMesh'.");
174 return EXIT_FAILURE;
175 }
176
177 if (keep_materials_arg.getValue())
178 {
180 result_mesh.get());
181 }
182
183 std::string output_name(mesh_out_arg.getValue());
185 {
186 output_name.append(".vtu");
187 }
188
189 INFO(
"Writing mesh '{:s}' ... ", output_name);
190 auto const data_mode =
191 use_ascii_arg.getValue() ? vtkXMLWriter::Ascii : vtkXMLWriter::Binary;
192
195
196 return EXIT_SUCCESS;
197}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
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.
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)