OGS
PartitionMesh.cpp File Reference

Detailed Description

A tool for mesh partitioning.

Date
2016.05

Definition in file PartitionMesh.cpp.

#include <tclap/CmdLine.h>
#include "BaseLib/CPUTime.h"
#include "BaseLib/FileTools.h"
#include "BaseLib/Logging.h"
#include "BaseLib/MPI.h"
#include "BaseLib/RunTime.h"
#include "BaseLib/TCLAPArguments.h"
#include "InfoLib/GitInfo.h"
#include "MeshLib/IO/readMeshFromFile.h"
#include "Metis.h"
#include "NodeWiseMeshPartitioner.h"
Include dependency graph for PartitionMesh.cpp:

Go to the source code of this file.

Functions

void addGlobalIDsToMesh (MeshLib::Properties &mesh_properties, MeshLib::MeshItemType const mesh_item_type, std::size_t const number_of_items)
 
void addGlobalIDsToMesh (MeshLib::Mesh &mesh)
 
int main (int argc, char *argv[])
 

Function Documentation

◆ addGlobalIDsToMesh() [1/2]

void addGlobalIDsToMesh ( MeshLib::Mesh & mesh)

Definition at line 49 of file PartitionMesh.cpp.

50{
51 auto& mesh_properties = mesh.getProperties();
52
54 mesh.getNumberOfNodes());
55 INFO("Property {} is added to mesh {}",
57
59 mesh.getNumberOfElements());
60 INFO("Property {} is added to mesh {}",
62}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:36
void addGlobalIDsToMesh(MeshLib::Properties &mesh_properties, MeshLib::MeshItemType const mesh_item_type, std::size_t const number_of_items)
Properties & getProperties()
Definition Mesh.h:136
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:105
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:102
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:99
constexpr std::string_view globalIDString(MeshLib::MeshItemType const mesh_item_type)
Definition Properties.h:221

References addGlobalIDsToMesh(), MeshLib::Cell, MeshLib::Mesh::getName(), MeshLib::Mesh::getNumberOfElements(), MeshLib::Mesh::getNumberOfNodes(), MeshLib::Mesh::getProperties(), MeshLib::globalIDString(), INFO(), and MeshLib::Node.

◆ addGlobalIDsToMesh() [2/2]

void addGlobalIDsToMesh ( MeshLib::Properties & mesh_properties,
MeshLib::MeshItemType const mesh_item_type,
std::size_t const number_of_items )

Definition at line 30 of file PartitionMesh.cpp.

33{
34 if (!mesh_properties.existsPropertyVector<std::size_t>(
35 MeshLib::globalIDString(mesh_item_type), mesh_item_type, 1))
36 {
37 auto* global_ids = mesh_properties.createNewPropertyVector<std::size_t>(
38 MeshLib::globalIDString(mesh_item_type), mesh_item_type,
39 number_of_items, 1);
40 if (!global_ids)
41 {
42 OGS_FATAL("Could not create PropertyVector '{}'.",
43 MeshLib::globalIDString(mesh_item_type));
44 }
45 global_ids->assign(ranges::views::iota(0u, number_of_items));
46 }
47}
#define OGS_FATAL(...)
Definition Error.h:26
bool existsPropertyVector(std::string_view name) const
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)

References MeshLib::Properties::createNewPropertyVector(), MeshLib::Properties::existsPropertyVector(), MeshLib::globalIDString(), and OGS_FATAL.

Referenced by addGlobalIDsToMesh(), and main().

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 64 of file PartitionMesh.cpp.

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
116 auto log_level_arg = BaseLib::makeLogLevelArg();
117 cmd.add(log_level_arg);
118
119 // All the remaining arguments are used as file names for boundary/subdomain
120 // meshes.
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
127 BaseLib::MPI::Setup mpi_setup(argc, argv);
128 BaseLib::initOGSLogger(log_level_arg.getValue());
129
130 const auto output_directory = output_directory_arg.getValue();
131 BaseLib::createOutputDirectory(output_directory);
132
133 BaseLib::RunTime run_timer;
134 run_timer.start();
135 BaseLib::CPUTime CPU_timer;
136 CPU_timer.start();
137
138 const std::string input_file_name_wo_extension =
139 BaseLib::dropFileExtension(mesh_input.getValue());
140 std::unique_ptr<MeshLib::Mesh> mesh_ptr(
141 MeshLib::IO::readMeshFromFile(input_file_name_wo_extension + ".vtu"));
142 INFO("Mesh '{:s}' read: {:d} nodes, {:d} elements.",
143 mesh_ptr->getName(),
144 mesh_ptr->getNumberOfNodes(),
145 mesh_ptr->getNumberOfElements());
146
147 addGlobalIDsToMesh(*mesh_ptr);
148
149 std::string const output_file_name_wo_extension = BaseLib::joinPaths(
150 output_directory,
151 BaseLib::extractBaseNameWithoutExtension(mesh_input.getValue()));
152
153 if (ogs2metis_flag.getValue())
154 {
155 INFO("Write the mesh into METIS input file.");
156 ApplicationUtils::writeMETIS(mesh_ptr->getElements(),
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 {
176 OGS_FATAL(
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 // Execute mpmetis via system(...)
189 if (exe_metis_flag.getValue())
190 {
191 INFO("METIS is running ...");
192 const std::string exe_name = argv[0];
193 const std::string exe_path = BaseLib::extractPath(exe_name);
194 INFO("Path to mpmetis is: \n\t{:s}", exe_path);
195
196 const std::string mpmetis_com =
197 BaseLib::joinPaths(exe_path, "mpmetis") + " -gtype=nodal " + "\"" +
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(
210 readMetisData(metis_mesh, num_partitions,
211 mesh_partitioner.mesh().getNumberOfNodes()));
212
213 // Remove metis partitioning files only if metis was run internally.
214 if (exe_metis_flag.getValue())
215 {
216 removeMetisPartitioningFiles(metis_mesh, num_partitions);
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
231 addGlobalIDsToMesh(*mesh);
232
233 std::string const other_mesh_output_file_name_wo_extension =
235 output_directory,
237 auto partitions = mesh_partitioner.partitionOtherMesh(*mesh);
238
239 auto partitioned_properties = partitionProperties(mesh, partitions);
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
248 BaseLib::RunTime io_run_timer;
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",
252 io_run_timer.elapsed());
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}
std::string getValue(std::string const &line, std::string const &val_name, bool is_string)
Count CPU time.
Definition CPUTime.h:23
void start()
Start the timer.
Definition CPUTime.h:26
double elapsed() const
Get the elapsed time after started.
Definition CPUTime.h:29
Count the running time.
Definition RunTime.h:29
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:42
void start()
Start the timer.
Definition RunTime.h:32
void writeMETIS(std::vector< MeshLib::Element * > const &elements, const std::string &file_name)
Definition Metis.cpp:19
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)
Definition Metis.cpp:90
std::vector< std::size_t > readMetisData(const std::string &file_name_base, long const number_of_partitions, std::size_t const number_of_nodes)
Definition Metis.cpp:45
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
Definition Logging.cpp:64
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)

References addGlobalIDsToMesh(), BaseLib::createOutputDirectory(), BaseLib::dropFileExtension(), BaseLib::CPUTime::elapsed(), BaseLib::RunTime::elapsed(), BaseLib::extractBaseNameWithoutExtension(), BaseLib::extractPath(), MeshLib::Mesh::getNumberOfNodes(), INFO(), BaseLib::initOGSLogger(), BaseLib::joinPaths(), BaseLib::makeLogLevelArg(), ApplicationUtils::NodeWiseMeshPartitioner::mesh(), OGS_FATAL, GitInfoLib::GitInfo::ogs_version, ApplicationUtils::NodeWiseMeshPartitioner::partitionByMETIS(), ApplicationUtils::NodeWiseMeshPartitioner::partitionOtherMesh(), ApplicationUtils::partitionProperties(), MeshLib::IO::readMeshFromFile(), ApplicationUtils::readMetisData(), ApplicationUtils::removeMetisPartitioningFiles(), ApplicationUtils::NodeWiseMeshPartitioner::renumberBulkIdsProperty(), ApplicationUtils::NodeWiseMeshPartitioner::resetPartitionIdsForNodes(), BaseLib::CPUTime::start(), BaseLib::RunTime::start(), ApplicationUtils::NodeWiseMeshPartitioner::write(), ApplicationUtils::writeMETIS(), and ApplicationUtils::NodeWiseMeshPartitioner::writeOtherMesh().