60int main(
int argc,
char* argv[])
63 "Structured mesh generator.\n"
64 "The documentation is available at "
65 "https://docs.opengeosys.org/docs/tools/meshing/"
66 "structured-mesh-generation.\n\n"
67 "OpenGeoSys-6 software, version " +
70 "Copyright (c) 2012-2024, OpenGeoSys Community "
71 "(http://www.opengeosys.org)",
74 auto tclapOutput = std::make_unique<BaseLib::TCLAPCustomOutput>();
75 cmd.setOutput(tclapOutput.get());
77 std::vector<std::string> allowed_ele_types;
78 allowed_ele_types.emplace_back(
"line");
79 allowed_ele_types.emplace_back(
"tri");
80 allowed_ele_types.emplace_back(
"quad");
81 allowed_ele_types.emplace_back(
"hex");
82 allowed_ele_types.emplace_back(
"prism");
83 allowed_ele_types.emplace_back(
"tet");
84 allowed_ele_types.emplace_back(
"pyramid");
85 TCLAP::ValuesConstraint<std::string> allowedVals(allowed_ele_types);
86 TCLAP::ValueArg<std::string> eleTypeArg(
88 "element type to be created: line | tri | quad | hex | prism | tet | "
90 true,
"line", &allowedVals);
92 TCLAP::ValueArg<std::string> mesh_out(
93 "o",
"mesh-output-file",
94 "the name of the file the mesh will be written to",
true,
"",
95 "file name of output mesh");
97 TCLAP::ValueArg<double> lengthXArg(
98 "",
"lx",
"length of a domain in x direction",
false, 10.0,
"real");
100 TCLAP::ValueArg<double> lengthYArg(
101 "",
"ly",
"length of a domain in y direction",
false, 10.0,
"real");
103 TCLAP::ValueArg<double> lengthZArg(
104 "",
"lz",
"length of a domain in z direction",
false, 10.0,
"real");
106 TCLAP::ValueArg<unsigned> nsubdivXArg(
107 "",
"nx",
"the number of subdivision in x direction",
false, 10,
109 cmd.add(nsubdivXArg);
110 TCLAP::ValueArg<unsigned> nsubdivYArg(
111 "",
"ny",
"the number of subdivision in y direction",
false, 10,
113 cmd.add(nsubdivYArg);
114 TCLAP::ValueArg<unsigned> nsubdivZArg(
115 "",
"nz",
"the number of subdivision in z direction",
false, 10,
117 cmd.add(nsubdivZArg);
119 TCLAP::ValueArg<double> d0XArg(
120 "",
"dx0",
"initial cell length in x direction",
false, 1,
"real");
122 TCLAP::ValueArg<double> d0YArg(
123 "",
"dy0",
"initial cell length in y direction",
false, 1,
"real");
125 TCLAP::ValueArg<double> d0ZArg(
126 "",
"dz0",
"initial cell length in z direction",
false, 1,
"real");
128 TCLAP::ValueArg<double> dmaxXArg(
129 "",
"dx-max",
"maximum cell length in x direction",
false,
130 std::numeric_limits<double>::max(),
"real");
132 TCLAP::ValueArg<double> dmaxYArg(
133 "",
"dy-max",
"maximum cell length in y direction",
false,
134 std::numeric_limits<double>::max(),
"real");
136 TCLAP::ValueArg<double> dmaxZArg(
137 "",
"dz-max",
"maximum cell length in z direction",
false,
138 std::numeric_limits<double>::max(),
"real");
140 TCLAP::ValueArg<double> multiXArg(
"",
"mx",
"multiplier in x direction",
143 TCLAP::ValueArg<double> multiYArg(
"",
"my",
"multiplier in y direction",
146 TCLAP::ValueArg<double> multiZArg(
"",
"mz",
"multiplier in z direction",
149 TCLAP::ValueArg<double> originXArg(
150 "",
"ox",
"mesh origin (lower left corner) in x direction",
false, 0,
153 TCLAP::ValueArg<double> originYArg(
154 "",
"oy",
"mesh origin (lower left corner) in y direction",
false, 0,
157 TCLAP::ValueArg<double> originZArg(
158 "",
"oz",
"mesh origin (lower left corner) in z direction",
false, 0,
163 cmd.parse(argc, argv);
165 MPI_Init(&argc, &argv);
167 const std::string eleTypeName(eleTypeArg.getValue());
172 bool dim_used[3] = {
false};
173 for (
unsigned i = 0; i < dim; i++)
178 std::vector<TCLAP::ValueArg<double>*> vec_lengthArg = {
179 &lengthXArg, &lengthYArg, &lengthZArg};
180 std::vector<TCLAP::ValueArg<unsigned>*> vec_ndivArg = {
181 &nsubdivXArg, &nsubdivYArg, &nsubdivZArg};
182 std::vector<TCLAP::ValueArg<double>*> vec_d0Arg = {&d0XArg, &d0YArg,
184 std::vector<TCLAP::ValueArg<double>*> vec_dMaxArg = {&dmaxXArg, &dmaxYArg,
186 std::vector<TCLAP::ValueArg<double>*> vec_multiArg = {
187 &multiXArg, &multiYArg, &multiZArg};
189 {originXArg.getValue(), originYArg.getValue(), originZArg.getValue()});
191 const bool isLengthSet =
192 std::any_of(vec_lengthArg.begin(), vec_lengthArg.end(),
193 [&](TCLAP::ValueArg<double>* arg) { return arg->isSet(); });
196 ERR(
"Missing input: Length information is not provided at all.");
202 for (
unsigned i = 0; i < 3; i++)
204 if (dim_used[i] && !vec_lengthArg[i]->isSet())
206 ERR(
"Missing input: Length for dimension [{:d}] is required but "
216 std::vector<double> length(dim);
217 std::vector<unsigned> n_subdivision(dim);
218 std::vector<double> vec_dx(dim);
219 for (
unsigned i = 0; i < dim; i++)
221 length[i] = vec_lengthArg[i]->getValue();
222 n_subdivision[i] = vec_ndivArg[i]->getValue();
223 vec_dx[i] = length[i] / n_subdivision[i];
226 std::vector<std::unique_ptr<BaseLib::ISubdivision>> vec_div;
227 vec_div.reserve(dim);
228 for (
unsigned i = 0; i < dim; i++)
230 if (vec_multiArg[i]->isSet())
232 if (vec_ndivArg[i]->isSet())
235 if (vec_d0Arg[i]->isSet())
238 "Specifying all of --m?, --d?0 and --n? for coordinate "
239 "'?' is not supported.");
242 length[i], vec_ndivArg[i]->
getValue(),
248 length[i], vec_d0Arg[i]->
getValue(),
254 vec_div.emplace_back(
260 std::unique_ptr<MeshLib::Mesh> mesh;
265 *vec_div[0], origin));
269 *vec_div[0], *vec_div[1], origin));
273 *vec_div[0], *vec_div[1], origin));
277 *vec_div[0], *vec_div[1], *vec_div[2], origin));
281 length[0], length[1], length[2], n_subdivision[0],
282 n_subdivision[1], n_subdivision[2], origin));
286 *vec_div[0], *vec_div[1], *vec_div[2], origin));
290 *vec_div[0], *vec_div[1], *vec_div[2], origin));
293 ERR(
"Given element type is not supported.");
299 INFO(
"Mesh created: {:d} nodes, {:d} elements.",
300 mesh->getNumberOfNodes(), mesh->getNumberOfElements());
304 *(mesh.get()), std::filesystem::path(mesh_out.getValue()));