53{
54 TCLAP::CmdLine cmd(
55 "Structured mesh generator.\n"
56 "The documentation is available at "
57 "https://docs.opengeosys.org/docs/tools/meshing/"
58 "structured-mesh-generation.\n\n"
59 "OpenGeoSys-6 software, version " +
61 ".\n"
62 "Copyright (c) 2012-2026, OpenGeoSys Community "
63 "(http://www.opengeosys.org)",
65
66 std::vector<std::string> allowed_ele_types;
67 allowed_ele_types.emplace_back("line");
68 allowed_ele_types.emplace_back("tri");
69 allowed_ele_types.emplace_back("quad");
70 allowed_ele_types.emplace_back("hex");
71 allowed_ele_types.emplace_back("prism");
72 allowed_ele_types.emplace_back("tet");
73 allowed_ele_types.emplace_back("pyramid");
74 TCLAP::ValuesConstraint<std::string> allowedVals(allowed_ele_types);
75 TCLAP::ValueArg<std::string> eleTypeArg("e", "element-type",
76 "element type to be created", true,
77 "line", &allowedVals);
78 cmd.add(eleTypeArg);
79 TCLAP::ValueArg<std::string> mesh_out(
80 "o", "mesh-output-file",
81 "Output (.vtu). The name of the file the mesh will be written to", true,
82 "", "OUTPUT_FILE");
83 cmd.add(mesh_out);
84 TCLAP::ValueArg<double> lengthXArg("", "lx",
85 "length of a domain in x direction, "
86 "(min = 0)",
87 false, 10.0, "LENGTH_X");
88 cmd.add(lengthXArg);
89 TCLAP::ValueArg<double> lengthYArg("", "ly",
90 "length of a domain in y direction, "
91 "(min = 0)",
92 false, 10.0, "LENGTH_Y");
93 cmd.add(lengthYArg);
94 TCLAP::ValueArg<double> lengthZArg("", "lz",
95 "length of a domain in z direction, "
96 "(min = 0)",
97 false, 10.0, "LENGTH_Z");
98 cmd.add(lengthZArg);
99 TCLAP::ValueArg<unsigned> nsubdivXArg(
100 "", "nx",
101 "the number of subdivision in x direction, "
102 "(min = 0)",
103 false, 10, "SUBDIVISIONS_X");
104 cmd.add(nsubdivXArg);
105 TCLAP::ValueArg<unsigned> nsubdivYArg(
106 "", "ny",
107 "the number of subdivision in y direction, "
108 "(min = 0)",
109 false, 10, "SUBDIVISIONS_Y");
110 cmd.add(nsubdivYArg);
111 TCLAP::ValueArg<unsigned> nsubdivZArg(
112 "", "nz",
113 "the number of subdivision in z direction, "
114 "(min = 0)",
115 false, 10, "SUBDIVISIONS_Z");
116 cmd.add(nsubdivZArg);
117
118 TCLAP::ValueArg<double> d0XArg("", "dx0",
119 "initial cell length in x direction, "
120 "(min = 0)",
121 false, 1, "INITIAL_X");
122 cmd.add(d0XArg);
123 TCLAP::ValueArg<double> d0YArg("", "dy0",
124 "initial cell length in y direction, "
125 "(min = 0)",
126 false, 1, "INITIAL_Y");
127 cmd.add(d0YArg);
128 TCLAP::ValueArg<double> d0ZArg("", "dz0",
129 "initial cell length in z direction, "
130 "(min = 0)",
131 false, 1, "INITIAL_Z");
132 cmd.add(d0ZArg);
133 TCLAP::ValueArg<double> dmaxXArg("", "dx-max",
134 "maximum cell length in x direction, "
135 "(min = 0)",
136 false, std::numeric_limits<double>::max(),
137 "MAX_X");
138 cmd.add(dmaxXArg);
139 TCLAP::ValueArg<double> dmaxYArg("", "dy-max",
140 "maximum cell length in y direction, "
141 "(min = 0)",
142 false, std::numeric_limits<double>::max(),
143 "MAX_Y");
144 cmd.add(dmaxYArg);
145 TCLAP::ValueArg<double> dmaxZArg("", "dz-max",
146 "maximum cell length in z direction, "
147 "(min = 0)",
148 false, std::numeric_limits<double>::max(),
149 "MAX_Z");
150 cmd.add(dmaxZArg);
151 TCLAP::ValueArg<double> multiXArg("", "mx", "multiplier in x direction",
152 false, 1, "MULTIPLIER_X");
153 cmd.add(multiXArg);
154 TCLAP::ValueArg<double> multiYArg("", "my", "multiplier in y direction",
155 false, 1, "MULTIPLIER_Y");
156 cmd.add(multiYArg);
157 TCLAP::ValueArg<double> multiZArg("", "mz", "multiplier in z direction",
158 false, 1, "MULTIPLIER_Z");
159 cmd.add(multiZArg);
160 TCLAP::ValueArg<double> originXArg(
161 "", "ox", "mesh origin (lower left corner) in x direction", false, 0,
162 "ORIGIN_X");
163 cmd.add(originXArg);
164 TCLAP::ValueArg<double> originYArg(
165 "", "oy", "mesh origin (lower left corner) in y direction", false, 0,
166 "ORIGIN_Y");
167 cmd.add(originYArg);
168 TCLAP::ValueArg<double> originZArg(
169 "", "oz", "mesh origin (lower left corner) in z direction", false, 0,
170 "ORIGIN_Z");
171 cmd.add(originZArg);
172
173
175 cmd.add(log_level_arg);
176 cmd.parse(argc, argv);
179
180 const std::string eleTypeName(eleTypeArg.getValue());
184
185 bool dim_used[3] = {false};
186 for (unsigned i = 0; i < dim; i++)
187 {
188 dim_used[i] = true;
189 }
190
191 std::vector<TCLAP::ValueArg<double>*> vec_lengthArg = {
192 &lengthXArg, &lengthYArg, &lengthZArg};
193 std::vector<TCLAP::ValueArg<unsigned>*> vec_ndivArg = {
194 &nsubdivXArg, &nsubdivYArg, &nsubdivZArg};
195 std::vector<TCLAP::ValueArg<double>*> vec_d0Arg = {&d0XArg, &d0YArg,
196 &d0ZArg};
197 std::vector<TCLAP::ValueArg<double>*> vec_dMaxArg = {&dmaxXArg, &dmaxYArg,
198 &dmaxZArg};
199 std::vector<TCLAP::ValueArg<double>*> vec_multiArg = {
200 &multiXArg, &multiYArg, &multiZArg};
202 {originXArg.getValue(), originYArg.getValue(), originZArg.getValue()});
203
204 const bool isLengthSet =
205 std::any_of(vec_lengthArg.begin(), vec_lengthArg.end(),
206 [&](TCLAP::ValueArg<double>* arg) { return arg->isSet(); });
207 if (!isLengthSet)
208 {
209 ERR(
"Missing input: Length information is not provided at all.");
210 return EXIT_FAILURE;
211 }
212 for (unsigned i = 0; i < 3; i++)
213 {
214 if (dim_used[i] && !vec_lengthArg[i]->isSet())
215 {
216 ERR(
"Missing input: Length for dimension [{:d}] is required but "
217 "missing.",
218 i);
219 return EXIT_FAILURE;
220 }
221 }
222
223 std::vector<double> length(dim);
224 std::vector<unsigned> n_subdivision(dim);
225 std::vector<double> vec_dx(dim);
226 for (unsigned i = 0; i < dim; i++)
227 {
228 length[i] = vec_lengthArg[i]->getValue();
229 n_subdivision[i] = vec_ndivArg[i]->getValue();
230 vec_dx[i] = length[i] / n_subdivision[i];
231 }
232
233 std::vector<std::unique_ptr<BaseLib::ISubdivision>> vec_div;
234 vec_div.reserve(dim);
235 for (unsigned i = 0; i < dim; i++)
236 {
237 if (vec_multiArg[i]->isSet())
238 {
239 if (vec_ndivArg[i]->isSet())
240 {
241
242 if (vec_d0Arg[i]->isSet())
243 {
245 "Specifying all of --m?, --d?0 and --n? for coordinate "
246 "'?' is not supported.");
247 }
249 length[i], vec_ndivArg[i]->
getValue(),
251 }
252 else
253 {
255 length[i], vec_d0Arg[i]->
getValue(),
257 }
258 }
259 else
260 {
261 vec_div.emplace_back(
263 }
264 }
265
266
267 std::unique_ptr<MeshLib::Mesh> mesh;
268 switch (eleType)
269 {
272 *vec_div[0], origin));
273 break;
276 *vec_div[0], *vec_div[1], origin));
277 break;
280 *vec_div[0], *vec_div[1], origin));
281 break;
284 *vec_div[0], *vec_div[1], *vec_div[2], origin));
285 break;
288 length[0], length[1], length[2], n_subdivision[0],
289 n_subdivision[1], n_subdivision[2], origin));
290 break;
293 *vec_div[0], *vec_div[1], *vec_div[2], origin));
294 break;
297 *vec_div[0], *vec_div[1], *vec_div[2], origin));
298 break;
299 default:
300 ERR(
"Given element type is not supported.");
301 break;
302 }
303
304 if (mesh)
305 {
306 INFO(
"Mesh created: {:d} nodes, {:d} elements.",
307 mesh->getNumberOfNodes(), mesh->getNumberOfElements());
308
309
311 *(mesh.get()), std::filesystem::path(mesh_out.getValue()));
312 }
313
314 return EXIT_SUCCESS;
315}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
GITINFOLIB_EXPORT const std::string ogs_version
int writeMeshToFile(const MeshLib::Mesh &mesh, std::filesystem::path const &file_path, std::set< std::string > variable_output_names)
MeshElemType String2MeshElemType(const std::string &s)
Given a string of the shortened name of the element type, this returns the corresponding MeshElemType...
MeshElemType
Types of mesh elements supported by OpenGeoSys. Values are from VTKCellType enum.
unsigned getDimension(MeshLib::MeshElemType eleType)