diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/CMakeLists.txt b/Applications/Utils/ModelPreparation/PartitionMesh/CMakeLists.txt index b331c0db9310b76826aa4d367fc56874c190a6c5..31311dcfe622542f87011fa5ed28b64c1a56c9c2 100644 --- a/Applications/Utils/ModelPreparation/PartitionMesh/CMakeLists.txt +++ b/Applications/Utils/ModelPreparation/PartitionMesh/CMakeLists.txt @@ -1,4 +1,5 @@ -add_executable(partmesh PartitionMesh.cpp NodeWiseMeshPartitioner.h NodeWiseMeshPartitioner.cpp) +add_executable(partmesh PartitionMesh.cpp Metis.cpp NodeWiseMeshPartitioner.cpp) + set_target_properties(partmesh PROPERTIES FOLDER Utilities) target_link_libraries(partmesh MeshLib) diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/Metis.cpp b/Applications/Utils/ModelPreparation/PartitionMesh/Metis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc2e2a2c9666ce3dc311183e3e961b71468a3d8a --- /dev/null +++ b/Applications/Utils/ModelPreparation/PartitionMesh/Metis.cpp @@ -0,0 +1,45 @@ +/** + * \file + * + * \copyright + * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#include <iostream> + +#include "BaseLib/Error.h" +#include "MeshLib/Elements/Element.h" + +namespace ApplicationUtils +{ +void writeMETIS(std::vector<MeshLib::Element*> const& elements, + const std::string& file_name) +{ + std::ofstream os(file_name, std::ios::trunc); + if (!os.is_open()) + { + OGS_FATAL("Error: cannot open file %s.", file_name.data()); + } + + if (!os.good()) + { + OGS_FATAL("Error: Cannot write in file %s.", file_name.data()); + } + + os << elements.size() << " \n"; + for (const auto* elem : elements) + { + os << elem->getNodeIndex(0) + 1; + for (unsigned j = 1; j < elem->getNumberOfNodes(); j++) + { + os << " " << elem->getNodeIndex(j) + 1; + } + os << "\n"; + } +} + +} // namespace ApplicationUtils diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/Metis.h b/Applications/Utils/ModelPreparation/PartitionMesh/Metis.h new file mode 100644 index 0000000000000000000000000000000000000000..a6cdf42ac69b73f190fee1652e09e40d1027a218 --- /dev/null +++ b/Applications/Utils/ModelPreparation/PartitionMesh/Metis.h @@ -0,0 +1,30 @@ +/** + * \file + * + * \copyright + * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#pragma once + +#include <string> +#include <vector> + +namespace MeshLib +{ +class Element; +} + +namespace ApplicationUtils +{ +/// Write elements as METIS graph file +/// \param elements The mesh elements. +/// \param file_name File name with an extension of mesh. +void writeMETIS(std::vector<MeshLib::Element*> const& elements, + const std::string& file_name); + +} // namespace ApplicationUtils diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp index 276a49210e061c2358016a35e41cf4a50d2fbe75..12fb355d0e57117576ae8d0671f1e553f8d7f06c 100644 --- a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp +++ b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp @@ -339,32 +339,6 @@ void NodeWiseMeshPartitioner::renumberNodeIndices( } } -void NodeWiseMeshPartitioner::writeMETIS(const std::string& file_name) -{ - std::ofstream os(file_name, std::ios::trunc); - if (!os.is_open()) - { - OGS_FATAL("Error: cannot open file %s.", file_name.data()); - } - - if (!os.good()) - { - OGS_FATAL("Error: Cannot write in file %s.", file_name.data()); - } - - std::vector<MeshLib::Element*> const& elements = _mesh->getElements(); - os << elements.size() << " \n"; - for (const auto* elem : elements) - { - os << elem->getNodeIndex(0) + 1; - for (unsigned j = 1; j < elem->getNumberOfNodes(); j++) - { - os << " " << elem->getNodeIndex(j) + 1; - } - os << "\n"; - } -} - NodeWiseMeshPartitioner::IntegerType NodeWiseMeshPartitioner::getNumberOfIntegerVariablesOfElements( const std::vector<const MeshLib::Element*>& elements) const diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.h b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.h index 2a27798a81ff3d1fffc85ac8fb6dd92904023c73..fa383273e197baf3f26a8cb424504a5368e79666 100644 --- a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.h +++ b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.h @@ -71,10 +71,6 @@ public: /// \param file_name_base The prefix of the file name. void readMetisData(const std::string& file_name_base); - /// Write mesh to METIS input file - /// \param file_name File name with an extension of mesh. - void writeMETIS(const std::string& file_name); - /// Write the partitions into ASCII files /// \param file_name_base The prefix of the file name. void writeASCII(const std::string& file_name_base); diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/PartitionMesh.cpp b/Applications/Utils/ModelPreparation/PartitionMesh/PartitionMesh.cpp index aeb2f027a64356ec516d5d2f531a9a091555a740..d41bf783e91e85785b4f321232818501ecd44c48 100644 --- a/Applications/Utils/ModelPreparation/PartitionMesh/PartitionMesh.cpp +++ b/Applications/Utils/ModelPreparation/PartitionMesh/PartitionMesh.cpp @@ -28,6 +28,7 @@ #include "MeshLib/IO/readMeshFromFile.h" #include "NodeWiseMeshPartitioner.h" +#include "Metis.h" int main(int argc, char* argv[]) { @@ -86,78 +87,78 @@ int main(int argc, char* argv[]) mesh_ptr->getNumberOfNodes(), mesh_ptr->getNumberOfElements()); + if (ogs2metis_flag.getValue()) + { + INFO("Write the mesh into METIS input file."); + ApplicationUtils::writeMETIS(mesh_ptr->getElements(), + BaseLib::dropFileExtension(ifile_name) + ".mesh"); + INFO("Total runtime: %g s.", run_timer.elapsed()); + INFO("Total CPU time: %g s.", CPU_timer.elapsed()); + + return EXIT_SUCCESS; + } + std::size_t const number_of_nodes(mesh_ptr->getNumberOfNodes()); std::size_t const number_of_elements(mesh_ptr->getNumberOfElements()); ApplicationUtils::NodeWiseMeshPartitioner mesh_partitioner( nparts.getValue(), std::move(mesh_ptr)); - if (ogs2metis_flag.getValue()) - { - INFO("Write the mesh into METIS input file."); - mesh_partitioner.writeMETIS(BaseLib::dropFileExtension(ifile_name) + - ".mesh"); - } - else + const int num_partitions = nparts.getValue(); + + // Execute mpmetis via system(...) + if (num_partitions > 1 && exe_metis_flag.getValue()) { - const int num_partitions = nparts.getValue(); + INFO("METIS is running ..."); + const std::string exe_name = argv[0]; + const std::string exe_path = BaseLib::extractPath(exe_name); + INFO("Path to mpmetis is: \n\t%s", exe_path.c_str()); - // Execute mpmetis via system(...) - if (num_partitions > 1 && exe_metis_flag.getValue()) - { - INFO("METIS is running ..."); - const std::string exe_name = argv[0]; - const std::string exe_path = BaseLib::extractPath(exe_name); - INFO("Path to mpmetis is: \n\t%s", exe_path.c_str()); - - const std::string mpmetis_com = - exe_path + "/mpmetis " + " -gtype=nodal " + file_name_base + - ".mesh " + std::to_string(nparts.getValue()); - - const int status = system(mpmetis_com.c_str()); - if (status != 0) - { - INFO("Failed in system calling."); - INFO("Return value of system call %d ", status); - return EXIT_FAILURE; - } - } - else if (num_partitions == 1 && exe_metis_flag.getValue()) + const std::string mpmetis_com = + exe_path + "/mpmetis " + " -gtype=nodal " + file_name_base + + ".mesh " + std::to_string(nparts.getValue()); + + const int status = system(mpmetis_com.c_str()); + if (status != 0) { - // The mpmetis tool can not be used for 'partitioning' in only one - // domain. For this reason the according files are written for just - // one domain in the metis output format in the following. - auto writePartitionFile = - [&file_name_base](std::string const& file_name_extension, - std::size_t number) { - std::string const name(file_name_base + - file_name_extension); - std::ofstream os(name); - if (!os) - OGS_FATAL("Couldn't open file '%s' for writing.", - name.c_str()); - for (std::size_t n(0); n < number; ++n) - os << "0\n"; - }; - - writePartitionFile(".mesh.npart.1", number_of_nodes); - writePartitionFile(".mesh.epart.1", number_of_elements); + INFO("Failed in system calling."); + INFO("Return value of system call %d ", status); + return EXIT_FAILURE; } + } + else if (num_partitions == 1 && exe_metis_flag.getValue()) + { + // The mpmetis tool can not be used for 'partitioning' in only one + // domain. For this reason the according files are written for just + // one domain in the metis output format in the following. + auto writePartitionFile = [&file_name_base]( + std::string const& file_name_extension, + std::size_t number) { + std::string const name(file_name_base + file_name_extension); + std::ofstream os(name); + if (!os) + OGS_FATAL("Couldn't open file '%s' for writing.", name.c_str()); + for (std::size_t n(0); n < number; ++n) + os << "0\n"; + }; + + writePartitionFile(".mesh.npart.1", number_of_nodes); + writePartitionFile(".mesh.epart.1", number_of_elements); + } - mesh_partitioner.readMetisData(file_name_base); + mesh_partitioner.readMetisData(file_name_base); - INFO("Partitioning the mesh in the node wise way ..."); - mesh_partitioner.partitionByMETIS(lh_elems_flag.getValue()); - if (ascii_flag.getValue()) - { - INFO("Write the data of partitions into ASCII files ..."); - mesh_partitioner.writeASCII(file_name_base); - } - else - { - INFO("Write the data of partitions into binary files ..."); - mesh_partitioner.writeBinary(file_name_base); - } + INFO("Partitioning the mesh in the node wise way ..."); + mesh_partitioner.partitionByMETIS(lh_elems_flag.getValue()); + if (ascii_flag.getValue()) + { + INFO("Write the data of partitions into ASCII files ..."); + mesh_partitioner.writeASCII(file_name_base); + } + else + { + INFO("Write the data of partitions into binary files ..."); + mesh_partitioner.writeBinary(file_name_base); } INFO("Total runtime: %g s.", run_timer.elapsed());