65{
66 TCLAP::CmdLine cmd(
67 "Partition a mesh for parallel computing."
68 "The tasks of this tool are in twofold:\n"
69 "1. Convert mesh file to the input file of the partitioning tool,\n"
70 "2. Partition a mesh using the partitioning tool,\n"
71 "\tcreate the mesh data of each partition,\n"
72 "\trenumber the node indices of each partition,\n"
73 "\tand output the results for parallel computing.\n"
74 "Note: If this tool is installed as a system command,\n"
75 "\tthe command must be run with its full path.\n\n"
76 "OpenGeoSys-6 software, version " +
78 ".\n"
79 "Copyright (c) 2012-2025, OpenGeoSys Community "
80 "(http://www.opengeosys.org)",
82 TCLAP::ValueArg<std::string> mesh_input(
83 "i", "mesh-input-file",
84 "Input (.vtu). The name of the file containing the input mesh", true,
85 "", "INPUT_FILE");
86 cmd.add(mesh_input);
87
88 TCLAP::ValueArg<std::string> metis_mesh_input(
89 "x", "metis-mesh-input-file",
90 "Input (.mesh). Base name (without .mesh extension) of the file "
91 "containing the metis input mesh",
92 false, "", "BASE_FILENAME_INPUT");
93 cmd.add(metis_mesh_input);
94
95 TCLAP::ValueArg<std::string> output_directory_arg(
96 "o", "output", "Output. Directory name for the output files", false, "",
97 "OUTPUT_PATH");
98 cmd.add(output_directory_arg);
99
100 TCLAP::ValueArg<int> nparts("n", "np",
101 "the number of partitions, "
102 "(min = 0)",
103 false, 2, "N_PARTS");
104 cmd.add(nparts);
105
106 TCLAP::SwitchArg ogs2metis_flag(
107 "s", "ogs2metis",
108 "Indicator to convert the ogs mesh file to METIS input file", cmd,
109 false);
110
111 TCLAP::SwitchArg exe_metis_flag(
112 "m", "exe_metis", "Call mpmetis inside the programme via system().",
113 false);
114 cmd.add(exe_metis_flag);
115
117 cmd.add(log_level_arg);
118
119
120
121 TCLAP::UnlabeledMultiArg<std::string> other_meshes_filenames_arg(
122 "other_meshes_filenames", "mesh file names.", false, "file");
123 cmd.add(other_meshes_filenames_arg);
124
125 cmd.parse(argc, argv);
126
129
130 const auto output_directory = output_directory_arg.getValue();
132
137
138 const std::string input_file_name_wo_extension =
140 std::unique_ptr<MeshLib::Mesh> mesh_ptr(
142 INFO(
"Mesh '{:s}' read: {:d} nodes, {:d} elements.",
143 mesh_ptr->getName(),
144 mesh_ptr->getNumberOfNodes(),
145 mesh_ptr->getNumberOfElements());
146
148
150 output_directory,
152
153 if (ogs2metis_flag.getValue())
154 {
155 INFO(
"Write the mesh into METIS input file.");
157 output_file_name_wo_extension + ".mesh");
158 INFO(
"Total runtime: {:g} s.", run_timer.
elapsed());
159 INFO(
"Total CPU time: {:g} s.", CPU_timer.
elapsed());
160
161 return EXIT_SUCCESS;
162 }
163
165 nparts.getValue(), std::move(mesh_ptr));
166
167 const int num_partitions = nparts.getValue();
168
169 if (num_partitions < 1)
170 {
171 OGS_FATAL(
"Number of partitions must be positive.");
172 }
173
174 if (num_partitions == 1)
175 {
177 "Partitioning the mesh into one domain is unnecessary because OGS "
178 "reads vtu mesh data directly when called with 'mpirun bin/ogs "
179 "-np=1'.");
180 }
181
182 auto metis_mesh = output_file_name_wo_extension;
183 if (metis_mesh_input.getValue() != "")
184 {
185 metis_mesh = metis_mesh_input.getValue();
186 }
187
188
189 if (exe_metis_flag.getValue())
190 {
191 INFO(
"METIS is running ...");
192 const std::string exe_name = argv[0];
194 INFO(
"Path to mpmetis is: \n\t{:s}", exe_path);
195
196 const std::string mpmetis_com =
198 metis_mesh + ".mesh" + "\" " + std::to_string(nparts.getValue());
199
200 INFO(
"Running: {:s}", mpmetis_com);
201 const int status = system(mpmetis_com.c_str());
202 if (status != 0)
203 {
204 INFO(
"Failed in system calling.");
205 INFO(
"Return value of system call {:d} ", status);
206 return EXIT_FAILURE;
207 }
208 }
209 mesh_partitioner.resetPartitionIdsForNodes(
211 mesh_partitioner.mesh().getNumberOfNodes()));
212
213
214 if (exe_metis_flag.getValue())
215 {
217 }
218
219 INFO(
"Partitioning the mesh in the node wise way ...");
220 mesh_partitioner.partitionByMETIS();
221
222 INFO(
"Partitioning other meshes according to the main mesh partitions.");
223 for (
auto const& filename : other_meshes_filenames_arg.
getValue())
224 {
225 std::unique_ptr<MeshLib::Mesh> mesh(
227 INFO(
"Mesh '{:s}' from file '{:s}' read: {:d} nodes, {:d} elements.",
228 mesh->getName(), filename, mesh->getNumberOfNodes(),
229 mesh->getNumberOfElements());
230
232
233 std::string const other_mesh_output_file_name_wo_extension =
235 output_directory,
237 auto partitions = mesh_partitioner.partitionOtherMesh(*mesh);
238
240 mesh_partitioner.renumberBulkIdsProperty(partitions,
241 partitioned_properties);
242
243 mesh_partitioner.writeOtherMesh(
244 other_mesh_output_file_name_wo_extension, partitions,
245 partitioned_properties);
246 }
247
249 io_run_timer.
start();
250 mesh_partitioner.write(output_file_name_wo_extension);
251 INFO(
"Writing the partitions data into binary files took {:g} s",
253
254 INFO(
"Total runtime: {:g} s.", run_timer.
elapsed());
255 INFO(
"Total CPU time: {:g} s.", CPU_timer.
elapsed());
256
257 return EXIT_SUCCESS;
258}
void start()
Start the timer.
double elapsed() const
Get the elapsed time after started.
double elapsed() const
Get the elapsed time in seconds.
void start()
Start the timer.
void writeMETIS(std::vector< MeshLib::Element * > const &elements, const std::string &file_name)
MeshLib::Properties partitionProperties(std::unique_ptr< MeshLib::Mesh > const &mesh, std::vector< Partition > &partitions)
Partition existing properties and add vtkGhostType cell data array property.
void removeMetisPartitioningFiles(std::string const &file_name_base, long const number_of_partitions)
std::vector< std::size_t > readMetisData(const std::string &file_name_base, long const number_of_partitions, std::size_t const number_of_nodes)
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
std::string extractPath(std::string const &pathname)
std::string extractBaseNameWithoutExtension(std::string const &pathname)
std::string dropFileExtension(std::string const &filename)
std::string joinPaths(std::string const &pathA, std::string const &pathB)
bool createOutputDirectory(std::string const &dir)
GITINFOLIB_EXPORT const std::string ogs_version
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)