166int main(
int argc,
char* argv[])
169 "Structured mesh generator.\n"
170 "The documentation is available at "
171 "https://docs.opengeosys.org/docs/tools/meshing/"
172 "structured-mesh-generation.\n\n"
173 "OpenGeoSys-6 software, version " +
176 "Copyright (c) 2012-2026, OpenGeoSys Community "
177 "(http://www.opengeosys.org)",
180 std::vector<std::string> allowed_ele_types;
181 allowed_ele_types.emplace_back(
"line");
182 allowed_ele_types.emplace_back(
"tri");
183 allowed_ele_types.emplace_back(
"quad");
184 allowed_ele_types.emplace_back(
"hex");
185 allowed_ele_types.emplace_back(
"prism");
186 allowed_ele_types.emplace_back(
"tet");
187 allowed_ele_types.emplace_back(
"pyramid");
188 TCLAP::ValuesConstraint<std::string> allowedVals(allowed_ele_types);
189 TCLAP::ValueArg<std::string> eleTypeArg(
"e",
"element-type",
190 "element type to be created",
true,
191 "line", &allowedVals);
193 TCLAP::ValueArg<std::string> mesh_out(
194 "o",
"mesh-output-file",
195 "Output (.vtu). The name of the file the mesh will be written to",
true,
198 TCLAP::ValueArg<double> lengthXArg(
"",
"lx",
199 "length of a domain in x direction, "
201 false, 10.0,
"LENGTH_X");
203 TCLAP::ValueArg<double> lengthYArg(
"",
"ly",
204 "length of a domain in y direction, "
206 false, 10.0,
"LENGTH_Y");
208 TCLAP::ValueArg<double> lengthZArg(
"",
"lz",
209 "length of a domain in z direction, "
211 false, 10.0,
"LENGTH_Z");
213 TCLAP::ValueArg<unsigned> nsubdivXArg(
215 "the number of subdivision in x direction, "
217 false, 10,
"SUBDIVISIONS_X");
218 cmd.add(nsubdivXArg);
219 TCLAP::ValueArg<unsigned> nsubdivYArg(
221 "the number of subdivision in y direction, "
223 false, 10,
"SUBDIVISIONS_Y");
224 cmd.add(nsubdivYArg);
225 TCLAP::ValueArg<unsigned> nsubdivZArg(
227 "the number of subdivision in z direction, "
229 false, 10,
"SUBDIVISIONS_Z");
230 cmd.add(nsubdivZArg);
232 TCLAP::ValueArg<double> d0XArg(
"",
"dx0",
233 "initial cell length in x direction, "
235 false, 1,
"INITIAL_X");
237 TCLAP::ValueArg<double> d0YArg(
"",
"dy0",
238 "initial cell length in y direction, "
240 false, 1,
"INITIAL_Y");
242 TCLAP::ValueArg<double> d0ZArg(
"",
"dz0",
243 "initial cell length in z direction, "
245 false, 1,
"INITIAL_Z");
247 TCLAP::ValueArg<double> dmaxXArg(
"",
"dx-max",
248 "maximum cell length in x direction, "
250 false, std::numeric_limits<double>::max(),
253 TCLAP::ValueArg<double> dmaxYArg(
"",
"dy-max",
254 "maximum cell length in y direction, "
256 false, std::numeric_limits<double>::max(),
259 TCLAP::ValueArg<double> dmaxZArg(
"",
"dz-max",
260 "maximum cell length in z direction, "
262 false, std::numeric_limits<double>::max(),
265 TCLAP::ValueArg<double> multiXArg(
"",
"mx",
"multiplier in x direction",
266 false, 1,
"MULTIPLIER_X");
268 TCLAP::ValueArg<double> multiYArg(
"",
"my",
"multiplier in y direction",
269 false, 1,
"MULTIPLIER_Y");
271 TCLAP::ValueArg<double> multiZArg(
"",
"mz",
"multiplier in z direction",
272 false, 1,
"MULTIPLIER_Z");
274 TCLAP::ValueArg<double> originXArg(
275 "",
"ox",
"mesh origin (lower left corner) in x direction",
false, 0,
278 TCLAP::ValueArg<double> originYArg(
279 "",
"oy",
"mesh origin (lower left corner) in y direction",
false, 0,
282 TCLAP::ValueArg<double> originZArg(
283 "",
"oz",
"mesh origin (lower left corner) in z direction",
false, 0,
288 cmd.add(log_level_arg);
289 cmd.parse(argc, argv);
293 const std::string eleTypeName(eleTypeArg.getValue());
298 bool dim_used[3] = {
false};
299 for (
unsigned i = 0; i < dim; i++)
304 std::vector<TCLAP::ValueArg<double>*> vec_lengthArg = {
305 &lengthXArg, &lengthYArg, &lengthZArg};
306 std::vector<TCLAP::ValueArg<unsigned>*> vec_ndivArg = {
307 &nsubdivXArg, &nsubdivYArg, &nsubdivZArg};
308 std::vector<TCLAP::ValueArg<double>*> vec_d0Arg = {&d0XArg, &d0YArg,
310 std::vector<TCLAP::ValueArg<double>*> vec_dMaxArg = {&dmaxXArg, &dmaxYArg,
312 std::vector<TCLAP::ValueArg<double>*> vec_multiArg = {
313 &multiXArg, &multiYArg, &multiZArg};
315 {originXArg.getValue(), originYArg.getValue(), originZArg.getValue()});
317 const bool isLengthSet =
318 std::any_of(vec_lengthArg.begin(), vec_lengthArg.end(),
319 [&](TCLAP::ValueArg<double>* arg) { return arg->isSet(); });
322 ERR(
"Missing input: Length information is not provided at all.");
325 for (
unsigned i = 0; i < 3; i++)
327 if (dim_used[i] && !vec_lengthArg[i]->isSet())
329 ERR(
"Missing input: Length for dimension [{:d}] is required but "
336 std::vector<double> length(dim);
337 std::vector<unsigned> n_subdivision(dim);
338 std::vector<double> vec_dx(dim);
339 for (
unsigned i = 0; i < dim; i++)
341 length[i] = vec_lengthArg[i]->getValue();
342 n_subdivision[i] = vec_ndivArg[i]->getValue();
343 vec_dx[i] = length[i] / n_subdivision[i];
346 std::vector<std::unique_ptr<BaseLib::ISubdivision>> vec_div;
347 vec_div.reserve(dim);
348 for (
unsigned i = 0; i < dim; i++)
350 if (vec_multiArg[i]->isSet())
352 if (vec_ndivArg[i]->isSet())
355 if (vec_d0Arg[i]->isSet())
358 "Specifying all of --m?, --d?0 and --n? for coordinate "
359 "'?' is not supported.");
362 length[i], vec_ndivArg[i]->
getValue(),
368 length[i], vec_d0Arg[i]->
getValue(),
374 vec_div.emplace_back(
380 std::unique_ptr<MeshLib::Mesh> mesh;
385 *vec_div[0], origin));
389 *vec_div[0], *vec_div[1], origin));
393 *vec_div[0], *vec_div[1], origin));
397 *vec_div[0], *vec_div[1], *vec_div[2], origin));
401 length[0], length[1], length[2], n_subdivision[0],
402 n_subdivision[1], n_subdivision[2], origin));
406 *vec_div[0], *vec_div[1], *vec_div[2], origin));
410 *vec_div[0], *vec_div[1], *vec_div[2], origin));
413 ERR(
"Given element type is not supported.");
422 INFO(
"Mesh created: {:d} nodes, {:d} elements.", mesh->getNumberOfNodes(),
423 mesh->getNumberOfElements());
425 auto const out_path = std::filesystem::path(mesh_out.getValue());
431 auto const base = (out_path.parent_path() / out_path.stem()).string();