34int main(
int argc,
char* argv[])
37 "Partition a mesh for parallel computing."
38 "The tasks of this tool are in twofold:\n"
39 "1. Convert mesh file to the input file of the partitioning tool,\n"
40 "2. Partition a mesh using the partitioning tool,\n"
41 "\tcreate the mesh data of each partition,\n"
42 "\trenumber the node indices of each partition,\n"
43 "\tand output the results for parallel computing.\n"
44 "Note: If this tool is installed as a system command,\n"
45 "\tthe command must be run with its full path.\n\n"
46 "OpenGeoSys-6 software, version " +
49 "Copyright (c) 2012-2024, OpenGeoSys Community "
50 "(http://www.opengeosys.org)",
52 TCLAP::ValueArg<std::string> mesh_input(
53 "i",
"mesh-input-file",
54 "the name of the file containing the input mesh",
true,
"",
55 "file name of input mesh");
58 TCLAP::ValueArg<std::string> metis_mesh_input(
59 "x",
"metis-mesh-input-file",
60 "base name (without .mesh extension) of the file containing the metis "
63 "base name (without .mesh extension) of the file containing the metis "
65 cmd.add(metis_mesh_input);
67 TCLAP::ValueArg<std::string> output_directory_arg(
68 "o",
"output",
"directory name for the output files",
false,
"",
70 cmd.add(output_directory_arg);
72 TCLAP::ValueArg<int> nparts(
"n",
"np",
"the number of partitions",
false, 2,
76 TCLAP::SwitchArg ogs2metis_flag(
78 "Indicator to convert the ogs mesh file to METIS input file", cmd,
81 TCLAP::SwitchArg exe_metis_flag(
82 "m",
"exe_metis",
"Call mpmetis inside the programme via system().",
84 cmd.add(exe_metis_flag);
86 TCLAP::ValueArg<std::string> log_level_arg(
88 "the verbosity of logging messages: none, error, warn, info, debug, "
97 cmd.add(log_level_arg);
101 TCLAP::UnlabeledMultiArg<std::string> other_meshes_filenames_arg(
102 "other_meshes_filenames",
"mesh file names.",
false,
"file");
103 cmd.add(other_meshes_filenames_arg);
105 cmd.parse(argc, argv);
108 MPI_Init(&argc, &argv);
112 spdlog::set_pattern(
"%^%l:%$ %v");
113 spdlog::set_error_handler(
114 [](
const std::string& msg)
116 std::cerr <<
"spdlog error: " << msg << std::endl;
117 OGS_FATAL(
"spdlog logger error occurred.");
120 const auto output_directory = output_directory_arg.getValue();
121 if (output_directory.length() > 0)
123 std::error_code mkdir_err;
124 if (std::filesystem::create_directories(output_directory, mkdir_err))
126 INFO(
"Output directory {:s} created.", output_directory);
128 else if (mkdir_err.value() != 0)
131 "Could not create output directory {:s}. Error code {:d}, {:s}",
132 output_directory, mkdir_err.value(), mkdir_err.message());
141 const std::string input_file_name_wo_extension =
143 std::unique_ptr<MeshLib::Mesh> mesh_ptr(
145 INFO(
"Mesh '{:s}' read: {:d} nodes, {:d} elements.",
147 mesh_ptr->getNumberOfNodes(),
148 mesh_ptr->getNumberOfElements());
154 if (ogs2metis_flag.getValue())
156 INFO(
"Write the mesh into METIS input file.");
158 output_file_name_wo_extension +
".mesh");
159 INFO(
"Total runtime: {:g} s.", run_timer.
elapsed());
160 INFO(
"Total CPU time: {:g} s.", CPU_timer.
elapsed());
169 nparts.getValue(), std::move(mesh_ptr));
171 const int num_partitions = nparts.getValue();
173 if (num_partitions < 1)
175 OGS_FATAL(
"Number of partitions must be positive.");
178 if (num_partitions == 1)
181 "Partitioning the mesh into one domain is unnecessary because OGS "
182 "reads vtu mesh data directly when called with 'mpirun bin/ogs "
186 auto metis_mesh = output_file_name_wo_extension;
187 if (metis_mesh_input.getValue() !=
"")
189 metis_mesh = metis_mesh_input.getValue();
193 if (exe_metis_flag.getValue())
195 INFO(
"METIS is running ...");
196 const std::string exe_name = argv[0];
198 INFO(
"Path to mpmetis is: \n\t{:s}", exe_path);
200 const std::string mpmetis_com =
202 metis_mesh +
".mesh" +
"' " + std::to_string(nparts.getValue());
204 INFO(
"Running: {:s}", mpmetis_com);
205 const int status = system(mpmetis_com.c_str());
208 INFO(
"Failed in system calling.");
209 INFO(
"Return value of system call {:d} ", status);
221 if (exe_metis_flag.getValue())
226 INFO(
"Partitioning the mesh in the node wise way ...");
229 INFO(
"Partitioning other meshes according to the main mesh partitions.");
230 for (
auto const& filename : other_meshes_filenames_arg.getValue())
232 std::unique_ptr<MeshLib::Mesh> mesh(
234 INFO(
"Mesh '{:s}' from file '{:s}' read: {:d} nodes, {:d} elements.",
235 mesh->getName(), filename, mesh->getNumberOfNodes(),
236 mesh->getNumberOfElements());
238 std::string
const other_mesh_output_file_name_wo_extension =
246 partitioned_properties);
249 other_mesh_output_file_name_wo_extension, partitions,
250 partitioned_properties);
254 io_run_timer.
start();
255 mesh_partitioner.
write(output_file_name_wo_extension);
256 INFO(
"Writing the partitions data into binary files took {:g} s",
259 INFO(
"Total runtime: {:g} s.", run_timer.
elapsed());
260 INFO(
"Total CPU time: {:g} s.", CPU_timer.
elapsed());