58int main(
int argc, 
char* argv[])
 
   61        "Structured mesh generator.\n" 
   62        "The documentation is available at " 
   63        "https://docs.opengeosys.org/docs/tools/meshing/" 
   64        "structured-mesh-generation.\n\n" 
   65        "OpenGeoSys-6 software, version " +
 
   68            "Copyright (c) 2012-2025, OpenGeoSys Community " 
   69            "(http://www.opengeosys.org)",
 
   72    std::vector<std::string> allowed_ele_types;
 
   73    allowed_ele_types.emplace_back(
"line");
 
   74    allowed_ele_types.emplace_back(
"tri");
 
   75    allowed_ele_types.emplace_back(
"quad");
 
   76    allowed_ele_types.emplace_back(
"hex");
 
   77    allowed_ele_types.emplace_back(
"prism");
 
   78    allowed_ele_types.emplace_back(
"tet");
 
   79    allowed_ele_types.emplace_back(
"pyramid");
 
   80    TCLAP::ValuesConstraint<std::string> allowedVals(allowed_ele_types);
 
   81    TCLAP::ValueArg<std::string> eleTypeArg(
"e", 
"element-type",
 
   82                                            "element type to be created", 
true,
 
   83                                            "line", &allowedVals);
 
   85    TCLAP::ValueArg<std::string> mesh_out(
 
   86        "o", 
"mesh-output-file",
 
   87        "Output (.vtu). The name of the file the mesh will be written to", 
true,
 
   90    TCLAP::ValueArg<double> lengthXArg(
"", 
"lx",
 
   91                                       "length of a domain in x direction, " 
   93                                       false, 10.0, 
"LENGTH_X");
 
   95    TCLAP::ValueArg<double> lengthYArg(
"", 
"ly",
 
   96                                       "length of a domain in y direction, " 
   98                                       false, 10.0, 
"LENGTH_Y");
 
  100    TCLAP::ValueArg<double> lengthZArg(
"", 
"lz",
 
  101                                       "length of a domain in z direction, " 
  103                                       false, 10.0, 
"LENGTH_Z");
 
  105    TCLAP::ValueArg<unsigned> nsubdivXArg(
 
  107        "the number of subdivision in x direction, " 
  109        false, 10, 
"SUBDIVISIONS_X");
 
  110    cmd.add(nsubdivXArg);
 
  111    TCLAP::ValueArg<unsigned> nsubdivYArg(
 
  113        "the number of subdivision in y direction, " 
  115        false, 10, 
"SUBDIVISIONS_Y");
 
  116    cmd.add(nsubdivYArg);
 
  117    TCLAP::ValueArg<unsigned> nsubdivZArg(
 
  119        "the number of subdivision in z direction, " 
  121        false, 10, 
"SUBDIVISIONS_Z");
 
  122    cmd.add(nsubdivZArg);
 
  124    TCLAP::ValueArg<double> d0XArg(
"", 
"dx0",
 
  125                                   "initial cell length in x direction, " 
  127                                   false, 1, 
"INITIAL_X");
 
  129    TCLAP::ValueArg<double> d0YArg(
"", 
"dy0",
 
  130                                   "initial cell length in y direction, " 
  132                                   false, 1, 
"INITIAL_Y");
 
  134    TCLAP::ValueArg<double> d0ZArg(
"", 
"dz0",
 
  135                                   "initial cell length in z direction, " 
  137                                   false, 1, 
"INITIAL_Z");
 
  139    TCLAP::ValueArg<double> dmaxXArg(
"", 
"dx-max",
 
  140                                     "maximum cell length in x direction, " 
  142                                     false, std::numeric_limits<double>::max(),
 
  145    TCLAP::ValueArg<double> dmaxYArg(
"", 
"dy-max",
 
  146                                     "maximum cell length in y direction, " 
  148                                     false, std::numeric_limits<double>::max(),
 
  151    TCLAP::ValueArg<double> dmaxZArg(
"", 
"dz-max",
 
  152                                     "maximum cell length in z direction, " 
  154                                     false, std::numeric_limits<double>::max(),
 
  157    TCLAP::ValueArg<double> multiXArg(
"", 
"mx", 
"multiplier in x direction",
 
  158                                      false, 1, 
"MULTIPLIER_X");
 
  160    TCLAP::ValueArg<double> multiYArg(
"", 
"my", 
"multiplier in y direction",
 
  161                                      false, 1, 
"MULTIPLIER_Y");
 
  163    TCLAP::ValueArg<double> multiZArg(
"", 
"mz", 
"multiplier in z direction",
 
  164                                      false, 1, 
"MULTIPLIER_Z");
 
  166    TCLAP::ValueArg<double> originXArg(
 
  167        "", 
"ox", 
"mesh origin (lower left corner) in x direction", 
false, 0,
 
  170    TCLAP::ValueArg<double> originYArg(
 
  171        "", 
"oy", 
"mesh origin (lower left corner) in y direction", 
false, 0,
 
  174    TCLAP::ValueArg<double> originZArg(
 
  175        "", 
"oz", 
"mesh origin (lower left corner) in z direction", 
false, 0,
 
  181    cmd.add(log_level_arg);
 
  182    cmd.parse(argc, argv);
 
  186    const std::string eleTypeName(eleTypeArg.getValue());
 
  191    bool dim_used[3] = {
false};
 
  192    for (
unsigned i = 0; i < dim; i++)
 
  197    std::vector<TCLAP::ValueArg<double>*> vec_lengthArg = {
 
  198        &lengthXArg, &lengthYArg, &lengthZArg};
 
  199    std::vector<TCLAP::ValueArg<unsigned>*> vec_ndivArg = {
 
  200        &nsubdivXArg, &nsubdivYArg, &nsubdivZArg};
 
  201    std::vector<TCLAP::ValueArg<double>*> vec_d0Arg = {&d0XArg, &d0YArg,
 
  203    std::vector<TCLAP::ValueArg<double>*> vec_dMaxArg = {&dmaxXArg, &dmaxYArg,
 
  205    std::vector<TCLAP::ValueArg<double>*> vec_multiArg = {
 
  206        &multiXArg, &multiYArg, &multiZArg};
 
  208        {originXArg.getValue(), originYArg.getValue(), originZArg.getValue()});
 
  210    const bool isLengthSet =
 
  211        std::any_of(vec_lengthArg.begin(), vec_lengthArg.end(),
 
  212                    [&](TCLAP::ValueArg<double>* arg) { return arg->isSet(); });
 
  215        ERR(
"Missing input: Length information is not provided at all.");
 
  218    for (
unsigned i = 0; i < 3; i++)
 
  220        if (dim_used[i] && !vec_lengthArg[i]->isSet())
 
  222            ERR(
"Missing input: Length for dimension [{:d}] is required but " 
  229    std::vector<double> length(dim);
 
  230    std::vector<unsigned> n_subdivision(dim);
 
  231    std::vector<double> vec_dx(dim);
 
  232    for (
unsigned i = 0; i < dim; i++)
 
  234        length[i] = vec_lengthArg[i]->getValue();
 
  235        n_subdivision[i] = vec_ndivArg[i]->getValue();
 
  236        vec_dx[i] = length[i] / n_subdivision[i];
 
  239    std::vector<std::unique_ptr<BaseLib::ISubdivision>> vec_div;
 
  240    vec_div.reserve(dim);
 
  241    for (
unsigned i = 0; i < dim; i++)
 
  243        if (vec_multiArg[i]->isSet())
 
  245            if (vec_ndivArg[i]->isSet())
 
  248                if (vec_d0Arg[i]->isSet())
 
  251                        "Specifying all of --m?, --d?0 and --n? for coordinate " 
  252                        "'?' is not supported.");
 
  255                    length[i], vec_ndivArg[i]->
getValue(),
 
  261                    length[i], vec_d0Arg[i]->
getValue(),
 
  267            vec_div.emplace_back(
 
  273    std::unique_ptr<MeshLib::Mesh> mesh;
 
  278                *vec_div[0], origin));
 
  282                *vec_div[0], *vec_div[1], origin));
 
  286                *vec_div[0], *vec_div[1], origin));
 
  290                *vec_div[0], *vec_div[1], *vec_div[2], origin));
 
  294                length[0], length[1], length[2], n_subdivision[0],
 
  295                n_subdivision[1], n_subdivision[2], origin));
 
  299                *vec_div[0], *vec_div[1], *vec_div[2], origin));
 
  303                *vec_div[0], *vec_div[1], *vec_div[2], origin));
 
  306            ERR(
"Given element type is not supported.");
 
  312        INFO(
"Mesh created: {:d} nodes, {:d} elements.",
 
  313             mesh->getNumberOfNodes(), mesh->getNumberOfElements());
 
  317            *(mesh.get()), std::filesystem::path(mesh_out.getValue()));