OGS
Layers2Grid.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include <tclap/CmdLine.h>
5
6#include <algorithm>
7#include <memory>
8#include <string>
9#include <vector>
10
12#include "BaseLib/Logging.h"
13#include "BaseLib/MPI.h"
15#include "GeoLib/AABB.h"
16#include "InfoLib/GitInfo.h"
17#include "MathLib/Point3d.h"
22
23int main(int argc, char* argv[])
24{
25 TCLAP::CmdLine cmd(
26 "Reads a list of 2D unstructured mesh layers and samples them onto a "
27 "structured grid of the same extent. Note, that a large cube size may "
28 "result in an undersampling of the original structure.\nCube sizes are "
29 "defines by x/y/z-parameters. For equilateral cubes, only the "
30 "x-parameter needs to be set.\n\n"
31 "OpenGeoSys-6 software, version " +
33 ".\n"
34 "Copyright (c) 2012-2026, OpenGeoSys Community "
35 "(http://www.opengeosys.org)",
37 TCLAP::SwitchArg dilate_arg(
38 "d", "dilate",
39 "assign mat IDs based on single nodes instead of a majority of nodes, "
40 "which can result in a slightly increased voxel grid extent",
41 false);
42 cmd.add(dilate_arg);
43
44 TCLAP::ValueArg<double> z_arg(
45 "z", "cellsize-z",
46 "edge length of cubes in z-direction (depth), "
47 "(min = 0)",
48 false, 1000, "CELLSIZE-Z");
49 cmd.add(z_arg);
50
51 TCLAP::ValueArg<double> y_arg(
52 "y", "cellsize-y",
53 "edge length of cubes in y-direction (latitude), "
54 "(min = 0)",
55 false, 1000, "CELLSIZE-Y");
56 cmd.add(y_arg);
57
58 TCLAP::ValueArg<double> x_arg(
59 "x", "cellsize-x",
60 "edge length of cubes in x-direction (longitude) or all directions, if "
61 "y and z are not set, (min = 0)",
62 true, 1000, "CELLSIZE-X");
63 cmd.add(x_arg);
64
65 TCLAP::ValueArg<std::string> output_arg(
66 "o", "output", "Output (.vtu). Name of output mesh file", true, "",
67 "OUTPUT_FILE");
68 cmd.add(output_arg);
69
70 TCLAP::ValueArg<std::string> input_arg(
71 "i", "input",
72 "Input (.vtu). Name of the input file list containing the paths the "
73 "all input layers "
74 "in correct order from top to bottom",
75 true, "", "INPUT_FILE_LIST");
76 cmd.add(input_arg);
77
78 auto log_level_arg = BaseLib::makeLogLevelArg();
79 cmd.add(log_level_arg);
80
81 cmd.parse(argc, argv);
82
83 BaseLib::MPI::Setup mpi_setup(argc, argv);
84 BaseLib::initOGSLogger(log_level_arg.getValue());
85
86 if ((y_arg.isSet() && !z_arg.isSet()) ||
87 ((!y_arg.isSet() && z_arg.isSet())))
88 {
89 ERR("For equilateral cubes, only x needs to be set. For unequal "
90 "cuboids, all three edge lengths (x/y/z) need to be specified.");
91 return EXIT_FAILURE;
92 }
93
94 double const x_size = x_arg.getValue();
95 double const y_size = (y_arg.isSet()) ? y_arg.getValue() : x_arg.getValue();
96 double const z_size = (z_arg.isSet()) ? z_arg.getValue() : x_arg.getValue();
97 std::array<double, 3> const cellsize = {x_size, y_size, z_size};
98
99 std::string const input_name = input_arg.getValue();
100 std::string const output_name = output_arg.getValue();
101 auto const layer_names = BaseLib::IO::readStringListFromFile(input_name);
102 if (layer_names.size() < 2)
103 {
104 ERR("At least two layers are required to create a 3D Mesh");
105 return EXIT_FAILURE;
106 }
107
108 std::vector<std::unique_ptr<MeshLib::Mesh>> layers;
109 layers.reserve(layer_names.size());
110 constexpr double minval = std::numeric_limits<double>::max();
111 constexpr double maxval = std::numeric_limits<double>::lowest();
112 std::pair<MathLib::Point3d, MathLib::Point3d> extent(
113 MathLib::Point3d{{minval, minval, minval}},
114 MathLib::Point3d{{maxval, maxval, maxval}});
115
116 for (auto const& layer : layer_names)
117 {
118 auto mesh(MeshLib::IO::readMeshFromFile(layer));
119 if (mesh == nullptr)
120 {
121 ERR("Input layer '{:s}' not found. Aborting...", layer);
122 return EXIT_FAILURE;
123 }
124 layers.emplace_back(mesh);
125 }
126 std::vector<MeshLib::Mesh const*> layers_ptr;
127 std::transform(std::begin(layers), std::end(layers),
128 std::back_inserter(layers_ptr),
129 [](auto const& layer) { return layer.get(); });
130 bool const dilate = dilate_arg.getValue();
132 createVoxelFromLayeredMesh(extent, layers_ptr, cellsize, dilate);
133 if (mesh == nullptr)
134 {
135 ERR("The VoxelGrid could not be created.");
136 return EXIT_FAILURE;
137 }
138 MeshLib::IO::VtuInterface vtu(mesh.get());
139 vtu.writeToFile(output_name);
140 return EXIT_SUCCESS;
141}
int main(int argc, char *argv[])
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
Reads and writes VtkXMLUnstructuredGrid-files (vtu) to and from OGS data structures....
bool writeToFile(std::filesystem::path const &file_path)
std::vector< std::string > readStringListFromFile(std::string const &filename)
Reads non-empty lines from a list of strings from a file into a vector.
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
Definition Logging.cpp:56
GITINFOLIB_EXPORT const std::string ogs_version
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)
std::unique_ptr< MeshLib::Mesh > createVoxelFromLayeredMesh(std::pair< MathLib::Point3d, MathLib::Point3d > &extent, std::vector< MeshLib::Mesh const * > const &layers, std::array< double, 3 > const cellsize, bool const dilate)