59{
   60    TCLAP::CmdLine cmd(
   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 " +
   67            ".\n"
   68            "Copyright (c) 2012-2025, OpenGeoSys Community "
   69            "(http://www.opengeosys.org)",
   71 
   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);
   84    cmd.add(eleTypeArg);
   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,
   88        "", "OUTPUT_FILE");
   89    cmd.add(mesh_out);
   90    TCLAP::ValueArg<double> lengthXArg("", "lx",
   91                                       "length of a domain in x direction, "
   92                                       "(min = 0)",
   93                                       false, 10.0, "LENGTH_X");
   94    cmd.add(lengthXArg);
   95    TCLAP::ValueArg<double> lengthYArg("", "ly",
   96                                       "length of a domain in y direction, "
   97                                       "(min = 0)",
   98                                       false, 10.0, "LENGTH_Y");
   99    cmd.add(lengthYArg);
  100    TCLAP::ValueArg<double> lengthZArg("", "lz",
  101                                       "length of a domain in z direction, "
  102                                       "(min = 0)",
  103                                       false, 10.0, "LENGTH_Z");
  104    cmd.add(lengthZArg);
  105    TCLAP::ValueArg<unsigned> nsubdivXArg(
  106        "", "nx",
  107        "the number of subdivision in x direction, "
  108        "(min = 0)",
  109        false, 10, "SUBDIVISIONS_X");
  110    cmd.add(nsubdivXArg);
  111    TCLAP::ValueArg<unsigned> nsubdivYArg(
  112        "", "ny",
  113        "the number of subdivision in y direction, "
  114        "(min = 0)",
  115        false, 10, "SUBDIVISIONS_Y");
  116    cmd.add(nsubdivYArg);
  117    TCLAP::ValueArg<unsigned> nsubdivZArg(
  118        "", "nz",
  119        "the number of subdivision in z direction, "
  120        "(min = 0)",
  121        false, 10, "SUBDIVISIONS_Z");
  122    cmd.add(nsubdivZArg);
  123    
  124    TCLAP::ValueArg<double> d0XArg("", "dx0",
  125                                   "initial cell length in x direction, "
  126                                   "(min = 0)",
  127                                   false, 1, "INITIAL_X");
  128    cmd.add(d0XArg);
  129    TCLAP::ValueArg<double> d0YArg("", "dy0",
  130                                   "initial cell length in y direction, "
  131                                   "(min = 0)",
  132                                   false, 1, "INITIAL_Y");
  133    cmd.add(d0YArg);
  134    TCLAP::ValueArg<double> d0ZArg("", "dz0",
  135                                   "initial cell length in z direction, "
  136                                   "(min = 0)",
  137                                   false, 1, "INITIAL_Z");
  138    cmd.add(d0ZArg);
  139    TCLAP::ValueArg<double> dmaxXArg("", "dx-max",
  140                                     "maximum cell length in x direction, "
  141                                     "(min = 0)",
  142                                     false, std::numeric_limits<double>::max(),
  143                                     "MAX_X");
  144    cmd.add(dmaxXArg);
  145    TCLAP::ValueArg<double> dmaxYArg("", "dy-max",
  146                                     "maximum cell length in y direction, "
  147                                     "(min = 0)",
  148                                     false, std::numeric_limits<double>::max(),
  149                                     "MAX_Y");
  150    cmd.add(dmaxYArg);
  151    TCLAP::ValueArg<double> dmaxZArg("", "dz-max",
  152                                     "maximum cell length in z direction, "
  153                                     "(min = 0)",
  154                                     false, std::numeric_limits<double>::max(),
  155                                     "MAX_Z");
  156    cmd.add(dmaxZArg);
  157    TCLAP::ValueArg<double> multiXArg("", "mx", "multiplier in x direction",
  158                                      false, 1, "MULTIPLIER_X");
  159    cmd.add(multiXArg);
  160    TCLAP::ValueArg<double> multiYArg("", "my", "multiplier in y direction",
  161                                      false, 1, "MULTIPLIER_Y");
  162    cmd.add(multiYArg);
  163    TCLAP::ValueArg<double> multiZArg("", "mz", "multiplier in z direction",
  164                                      false, 1, "MULTIPLIER_Z");
  165    cmd.add(multiZArg);
  166    TCLAP::ValueArg<double> originXArg(
  167        "", "ox", "mesh origin (lower left corner) in x direction", false, 0,
  168        "ORIGIN_X");
  169    cmd.add(originXArg);
  170    TCLAP::ValueArg<double> originYArg(
  171        "", "oy", "mesh origin (lower left corner) in y direction", false, 0,
  172        "ORIGIN_Y");
  173    cmd.add(originYArg);
  174    TCLAP::ValueArg<double> originZArg(
  175        "", "oz", "mesh origin (lower left corner) in z direction", false, 0,
  176        "ORIGIN_Z");
  177    cmd.add(originZArg);
  178 
  179    
  181    cmd.add(log_level_arg);
  182    cmd.parse(argc, argv);
  185 
  186    const std::string eleTypeName(eleTypeArg.getValue());
  190 
  191    bool dim_used[3] = {false};
  192    for (unsigned i = 0; i < dim; i++)
  193    {
  194        dim_used[i] = true;
  195    }
  196 
  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,
  202                                                       &d0ZArg};
  203    std::vector<TCLAP::ValueArg<double>*> vec_dMaxArg = {&dmaxXArg, &dmaxYArg,
  204                                                         &dmaxZArg};
  205    std::vector<TCLAP::ValueArg<double>*> vec_multiArg = {
  206        &multiXArg, &multiYArg, &multiZArg};
  208        {originXArg.getValue(), originYArg.getValue(), originZArg.getValue()});
  209 
  210    const bool isLengthSet =
  211        std::any_of(vec_lengthArg.begin(), vec_lengthArg.end(),
  212                    [&](TCLAP::ValueArg<double>* arg) { return arg->isSet(); });
  213    if (!isLengthSet)
  214    {
  215        ERR(
"Missing input: Length information is not provided at all.");
 
  216        return EXIT_FAILURE;
  217    }
  218    for (unsigned i = 0; i < 3; i++)
  219    {
  220        if (dim_used[i] && !vec_lengthArg[i]->isSet())
  221        {
  222            ERR(
"Missing input: Length for dimension [{:d}] is required but " 
  223                "missing.",
  224                i);
  225            return EXIT_FAILURE;
  226        }
  227    }
  228 
  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++)
  233    {
  234        length[i] = vec_lengthArg[i]->getValue();
  235        n_subdivision[i] = vec_ndivArg[i]->getValue();
  236        vec_dx[i] = length[i] / n_subdivision[i];
  237    }
  238 
  239    std::vector<std::unique_ptr<BaseLib::ISubdivision>> vec_div;
  240    vec_div.reserve(dim);
  241    for (unsigned i = 0; i < dim; i++)
  242    {
  243        if (vec_multiArg[i]->isSet())
  244        {
  245            if (vec_ndivArg[i]->isSet())
  246            {
  247                
  248                if (vec_d0Arg[i]->isSet())
  249                {
  251                        "Specifying all of --m?, --d?0 and --n? for coordinate "
  252                        "'?' is not supported.");
  253                }
  255                    length[i], vec_ndivArg[i]->
getValue(),
 
  257            }
  258            else
  259            {
  261                    length[i], vec_d0Arg[i]->
getValue(),
 
  263            }
  264        }
  265        else
  266        {
  267            vec_div.emplace_back(
  269        }
  270    }
  271 
  272    
  273    std::unique_ptr<MeshLib::Mesh> mesh;
  274    switch (eleType)
  275    {
  278                *vec_div[0], origin));
  279            break;
  282                *vec_div[0], *vec_div[1], origin));
  283            break;
  286                *vec_div[0], *vec_div[1], origin));
  287            break;
  290                *vec_div[0], *vec_div[1], *vec_div[2], origin));
  291            break;
  294                length[0], length[1], length[2], n_subdivision[0],
  295                n_subdivision[1], n_subdivision[2], origin));
  296            break;
  299                *vec_div[0], *vec_div[1], *vec_div[2], origin));
  300            break;
  303                *vec_div[0], *vec_div[1], *vec_div[2], origin));
  304            break;
  305        default:
  306            ERR(
"Given element type is not supported.");
 
  307            break;
  308    }
  309 
  310    if (mesh)
  311    {
  312        INFO(
"Mesh created: {:d} nodes, {:d} elements.",
 
  313             mesh->getNumberOfNodes(), mesh->getNumberOfElements());
  314 
  315        
  317            *(mesh.get()), std::filesystem::path(mesh_out.getValue()));
  318    }
  319 
  320    return EXIT_SUCCESS;
  321}
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)