30 auto const* surface_material_ids = materialIDs(*sfc_mesh);
31 auto* subsurface_material_ids = materialIDs(*subsurface_mesh);
33 if (!surface_material_ids)
35 OGS_FATAL(
"Surface mesh does not contain material IDs");
37 if (surface_material_ids->empty())
39 OGS_FATAL(
"Surface mesh material IDs doesn't contain any values");
41 if (!subsurface_material_ids)
43 OGS_FATAL(
"Subsurface mesh does not contain material IDs");
45 if (subsurface_material_ids->size() % surface_material_ids->size() != 0)
47 OGS_FATAL(
"Could not determine the number of subsurface layers.");
49 int const number_of_layers =
50 subsurface_material_ids->size() / surface_material_ids->size();
53 ranges::views::repeat_n(*surface_material_ids, number_of_layers) |
55 subsurface_material_ids->begin());
58int main(
int argc,
char* argv[])
61 "Creates a layered 3D OGS mesh from an existing 2D OGS mesh and a list "
62 "of raster files representing subsurface layers. Supported raster "
63 "formats are ArcGIS ascii rasters (*.asc), Surfer Grids (*.grd), or "
64 "gridded XYZ rasters (*.xyz)."
65 "Only input meshes consisting of line and triangle elements are "
66 "currently supported as mapping of quads might result in invalid mesh "
68 "OpenGeoSys-6 software, version " +
71 "Copyright (c) 2012-2026, OpenGeoSys Community "
72 "(http://www.opengeosys.org)",
75 TCLAP::SwitchArg use_ascii_arg(
"",
"ascii_output",
76 "Write VTU output in ASCII format.");
77 cmd.add(use_ascii_arg);
79 double min_thickness(std::numeric_limits<double>::epsilon());
80 TCLAP::ValueArg<double> min_thickness_arg(
82 "The minimum thickness of a layer to be integrated at any given "
83 "location, (min = 0)",
84 false, min_thickness,
"MIN_THICKNESS");
85 cmd.add(min_thickness_arg);
87 TCLAP::ValueArg<std::string> raster_path_arg(
89 "Input (.vtu). An ascii-file containing a list of input "
90 "raster files, starting from"
91 "top (DEM) to bottom",
92 true,
"",
"INPUT_FILE_LIST");
93 cmd.add(raster_path_arg);
95 TCLAP::SwitchArg keep_materials_arg(
96 "",
"keep-surface-material-ids",
97 "if the argument is present the materials defined in the surface mesh "
98 "are used to set the material information for the subsurface cells",
100 cmd.add(keep_materials_arg);
102 TCLAP::ValueArg<std::string> mesh_out_arg(
103 "o",
"output-mesh-file",
104 "Output (.vtu). The file name of the resulting 3D mesh",
true,
"",
106 cmd.add(mesh_out_arg);
108 TCLAP::ValueArg<std::string> mesh_arg(
109 "i",
"input-mesh-file",
110 "Input (.vtu). The file name of the 2D input mesh",
true,
"",
114 cmd.add(log_level_arg);
116 cmd.parse(argc, argv);
121 if (min_thickness_arg.isSet())
123 min_thickness = min_thickness_arg.getValue();
124 if (min_thickness < 0)
126 ERR(
"Minimum layer thickness must be non-negative value.");
131 INFO(
"Reading mesh '{:s}' ... ", mesh_arg.getValue());
132 std::unique_ptr<MeshLib::Mesh>
const sfc_mesh(
136 ERR(
"Error reading mesh '{:s}'.", mesh_arg.getValue());
139 if (sfc_mesh->getDimension() != 2)
141 ERR(
"Input mesh must be a 2D mesh.");
146 std::vector<std::string> raster_paths =
148 if (raster_paths.size() < 2)
150 ERR(
"At least two raster files needed to create 3D mesh.");
153 std::reverse(raster_paths.begin(), raster_paths.end());
158 if (!mapper.
createLayers(*sfc_mesh, *rasters, min_thickness))
165 ERR(
"Reading raster files.");
169 auto const result_mesh = mapper.
getMesh(
"SubsurfaceMesh");
170 if (result_mesh ==
nullptr)
172 ERR(
"Mapper returned empty result for 'SubsurfaceMesh'.");
176 if (keep_materials_arg.getValue())
182 std::string output_name(mesh_out_arg.getValue());
185 output_name.append(
".vtu");
188 INFO(
"Writing mesh '{:s}' ... ", output_name);
189 auto const data_mode =
190 use_ascii_arg.getValue() ? vtkXMLWriter::Ascii : vtkXMLWriter::Binary;