From ff9e84a73f8b3b8f4d6c326a2a190ffee1fc7cb1 Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <github@naumov.de>
Date: Sat, 23 Nov 2024 09:26:24 +0100
Subject: [PATCH] Use MPI::Setup wrapper for MPI_Init and Finalize

---
 .../LinearSolverLibrarySetup.h                |  7 ++--
 .../Utils/FileConverter/ConvertSHPToGLI.cpp   | 15 ++-------
 .../Utils/FileConverter/FEFLOW2OGS.cpp        | 16 ++-------
 Applications/Utils/FileConverter/GMSH2OGS.cpp | 16 ++-------
 .../Utils/FileConverter/GocadSGridReader.cpp  | 12 ++-----
 .../FileConverter/GocadTSurfaceReader.cpp     | 18 ++--------
 .../Utils/FileConverter/Mesh2Raster.cpp       | 18 ++--------
 .../Utils/FileConverter/Mesh2Shape.cpp        | 15 ++-------
 .../Utils/FileConverter/NetCdfConverter.cpp   | 27 ++-------------
 Applications/Utils/FileConverter/OGS2VTK.cpp  | 15 ++-------
 Applications/Utils/FileConverter/PVD2XDMF.cpp | 12 ++-----
 .../Utils/FileConverter/Raster2ASC.cpp        | 12 ++-----
 Applications/Utils/FileConverter/TIN2VTK.cpp  | 16 ++-------
 .../Utils/FileConverter/TecPlotTools.cpp      | 24 ++------------
 Applications/Utils/FileConverter/VTK2OGS.cpp  | 12 ++-----
 Applications/Utils/FileConverter/VTK2TIN.cpp  | 13 ++------
 .../Utils/FileConverter/convertGEO.cpp        | 12 ++-----
 .../generateMatPropsFromMatID.cpp             | 18 ++--------
 Applications/Utils/GeoTools/MoveGeometry.cpp  | 18 ++--------
 .../Utils/GeoTools/addDataToRaster.cpp        | 12 ++-----
 Applications/Utils/GeoTools/createRaster.cpp  | 12 ++-----
 .../Utils/GeoTools/generateGeometry.cpp       | 15 ++-------
 .../Utils/MeshEdit/AddElementQuality.cpp      | 15 ++-------
 .../Utils/MeshEdit/AddFaultToVoxelGrid.cpp    | 21 ++----------
 Applications/Utils/MeshEdit/AddLayer.cpp      | 21 ++----------
 ...CreateBoundaryConditionsAlongPolylines.cpp | 18 ++--------
 .../Utils/MeshEdit/ExtractBoundary.cpp        | 15 ++-------
 .../Utils/MeshEdit/ExtractMaterials.cpp       | 24 ++------------
 .../Utils/MeshEdit/ExtractSurface.cpp         | 18 ++--------
 Applications/Utils/MeshEdit/Layers2Grid.cpp   | 24 ++------------
 .../MeshEdit/MapGeometryToMeshSurface.cpp     | 15 ++-------
 Applications/Utils/MeshEdit/MeshMapping.cpp   | 30 ++---------------
 Applications/Utils/MeshEdit/MoveMesh.cpp      | 15 ++-------
 .../Utils/MeshEdit/NodeReordering.cpp         | 15 ++-------
 .../Utils/MeshEdit/PVTU2VTU/PVTU2VTU.cpp      | 15 ++-------
 .../Utils/MeshEdit/RemoveGhostData.cpp        | 12 ++-----
 Applications/Utils/MeshEdit/ReorderMesh.cpp   | 15 ++-------
 .../ResetPropertiesInPolygonalRegion.cpp      | 24 ++------------
 Applications/Utils/MeshEdit/Vtu2Grid.cpp      | 26 ++-------------
 .../MeshEdit/appendLinesAlongPolyline.cpp     | 21 ++----------
 Applications/Utils/MeshEdit/checkMesh.cpp     | 18 ++--------
 .../Utils/MeshEdit/convertToLinearMesh.cpp    | 18 ++--------
 .../MeshEdit/createLayeredMeshFromRasters.cpp | 33 ++-----------------
 .../Utils/MeshEdit/createQuadraticMesh.cpp    | 15 ++-------
 .../MeshEdit/createTetgenSmeshFromRasters.cpp | 33 ++-----------------
 .../Utils/MeshEdit/editMaterialID.cpp         | 24 ++------------
 .../Utils/MeshEdit/ipDataToPointCloud.cpp     | 12 ++-----
 Applications/Utils/MeshEdit/queryMesh.cpp     | 15 ++-------
 .../Utils/MeshEdit/removeMeshElements.cpp     | 30 ++---------------
 Applications/Utils/MeshEdit/reviseMesh.cpp    | 15 ++-------
 .../Utils/MeshEdit/swapNodeCoordinateAxes.cpp | 18 ++--------
 .../MeshGeoTools/AssignRasterDataToMesh.cpp   | 21 ++----------
 .../IntegrateBoreholesIntoMesh.cpp            | 33 ++-----------------
 .../Utils/MeshGeoTools/Raster2Mesh.cpp        | 15 ++-------
 .../MeshGeoTools/VerticalSliceFromLayers.cpp  | 24 ++------------
 ...computeSurfaceNodeIDsInPolygonalRegion.cpp | 12 ++-----
 .../constructMeshesFromGeometry.cpp           | 14 ++------
 .../createIntermediateRasters.cpp             | 24 ++------------
 .../Utils/MeshGeoTools/geometryToGmshGeo.cpp  | 21 ++----------
 .../Utils/MeshGeoTools/identifySubdomains.cpp | 12 ++-----
 .../ComputeNodeAreasFromSurfaceMesh.cpp       | 15 ++-------
 .../PartitionMesh/BinaryToPVTU.cpp            |  9 ++---
 .../PartitionMesh/PartitionMesh.cpp           | 18 ++--------
 .../convertVtkDataArrayToVtkDataArray.cpp     | 18 ++--------
 .../ModelPreparation/createNeumannBc.cpp      | 15 ++-------
 .../Utils/ModelPreparation/scaleProperty.cpp  | 12 ++-----
 .../PostProcessing/Raster2PointCloud.cpp      | 11 ++-----
 Applications/Utils/PostProcessing/postLIE.cpp | 12 ++-----
 .../Utils/SWMMConverter/SWMMConverter.cpp     | 18 ++--------
 .../createMeshElemPropertiesFromASCRaster.cpp | 12 ++-----
 .../generateStructuredMesh.cpp                | 18 ++--------
 71 files changed, 145 insertions(+), 1099 deletions(-)

diff --git a/Applications/ApplicationsLib/LinearSolverLibrarySetup.h b/Applications/ApplicationsLib/LinearSolverLibrarySetup.h
index 59c94cd317d..e6b48ce2f6a 100644
--- a/Applications/ApplicationsLib/LinearSolverLibrarySetup.h
+++ b/Applications/ApplicationsLib/LinearSolverLibrarySetup.h
@@ -19,6 +19,7 @@
 /// The default implementation is empty providing polymorphic behaviour when
 /// using this class.
 
+#include "BaseLib/MPI.h"
 #include "NumLib/DOF/GlobalMatrixProviders.h"
 
 #if defined(USE_PETSC)
@@ -28,9 +29,8 @@ namespace ApplicationsLib
 {
 struct LinearSolverLibrarySetup final
 {
-    LinearSolverLibrarySetup(int argc, char* argv[])
+    LinearSolverLibrarySetup(int argc, char* argv[]) : mpi_setup(argc, argv)
     {
-        MPI_Init(&argc, &argv);
         char help[] = "ogs6 with PETSc \n";
         PetscInitialize(&argc, &argv, nullptr, help);
         MPI_Comm_set_errhandler(PETSC_COMM_WORLD, MPI_ERRORS_RETURN);
@@ -40,8 +40,9 @@ struct LinearSolverLibrarySetup final
     {
         NumLib::cleanupGlobalMatrixProviders();
         PetscFinalize();
-        MPI_Finalize();
     }
+
+    BaseLib::MPI::Setup mpi_setup;
 };
 }    // ApplicationsLib
 #elif defined(USE_LIS)
diff --git a/Applications/Utils/FileConverter/ConvertSHPToGLI.cpp b/Applications/Utils/FileConverter/ConvertSHPToGLI.cpp
index 2fb39d512d6..6023763a1b0 100644
--- a/Applications/Utils/FileConverter/ConvertSHPToGLI.cpp
+++ b/Applications/Utils/FileConverter/ConvertSHPToGLI.cpp
@@ -14,10 +14,6 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 // STL
 #include <fstream>
 #include <vector>
@@ -25,6 +21,7 @@
 // ShapeLib
 #include <shapefil.h>
 
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/IO/XmlIO/Qt/XmlGmlInterface.h"
 #include "GeoLib/IO/XmlIO/Qt/XmlStnInterface.h"
@@ -185,9 +182,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::string fname(shapefile_arg.getValue());
 
@@ -207,9 +202,6 @@ int main(int argc, char* argv[])
             ERR("Shape file contains {:d} polylines.", number_of_elements);
             ERR("This programme only handles only files containing points.");
             SHPClose(hSHP);
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_SUCCESS;
         }
         SHPClose(hSHP);
@@ -304,8 +296,5 @@ int main(int argc, char* argv[])
         ERR("Could not open the database file.");
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/FEFLOW2OGS.cpp b/Applications/Utils/FileConverter/FEFLOW2OGS.cpp
index acd33c06c89..e299c2b56d2 100644
--- a/Applications/Utils/FileConverter/FEFLOW2OGS.cpp
+++ b/Applications/Utils/FileConverter/FEFLOW2OGS.cpp
@@ -14,12 +14,8 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
-// BaseLib
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/RunTime.h"
 #include "InfoLib/GitInfo.h"
 #ifndef WIN32
@@ -62,9 +58,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // *** read mesh
     INFO("Reading {:s}.", feflow_mesh_arg.getValue());
@@ -81,9 +75,6 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         INFO("Could not read mesh from {:s}.", feflow_mesh_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 #ifndef WIN32
@@ -99,8 +90,5 @@ int main(int argc, char* argv[])
     INFO("Writing {:s}.", ogs_mesh_fname);
     MeshLib::IO::writeMeshToFile(*mesh, ogs_mesh_fname);
     INFO("\tDone.");
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/GMSH2OGS.cpp b/Applications/Utils/FileConverter/GMSH2OGS.cpp
index a528076749b..6674dbc902f 100644
--- a/Applications/Utils/FileConverter/GMSH2OGS.cpp
+++ b/Applications/Utils/FileConverter/GMSH2OGS.cpp
@@ -19,12 +19,8 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
-// BaseLib
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/RunTime.h"
 #include "InfoLib/GitInfo.h"
 #ifndef WIN32
@@ -176,9 +172,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // *** read mesh
     INFO("Reading {:s}.", gmsh_mesh_arg.getValue());
@@ -194,9 +188,6 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         INFO("Could not read mesh from {:s}.", gmsh_mesh_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 #ifndef WIN32
@@ -279,8 +270,5 @@ int main(int argc, char* argv[])
     MeshLib::IO::writeMeshToFile(*mesh, ogs_mesh_arg.getValue());
 
     delete mesh;
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/GocadSGridReader.cpp b/Applications/Utils/FileConverter/GocadSGridReader.cpp
index 0f3e6784c14..a28124cc5c3 100644
--- a/Applications/Utils/FileConverter/GocadSGridReader.cpp
+++ b/Applications/Utils/FileConverter/GocadSGridReader.cpp
@@ -12,16 +12,13 @@
 #include <spdlog/spdlog.h>
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <fstream>
 #include <sstream>
 #include <string>
 
 #include "Applications/FileIO/GocadIO/GenerateFaceSetMeshes.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -61,9 +58,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // read the Gocad SGrid
     INFO("Start reading Gocad SGrid.");
@@ -82,8 +77,5 @@ int main(int argc, char* argv[])
 
     INFO("Writing mesh to '{:s}'.", mesh_output_arg.getValue());
     MeshLib::IO::writeMeshToFile(*mesh, mesh_output_arg.getValue());
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/GocadTSurfaceReader.cpp b/Applications/Utils/FileConverter/GocadTSurfaceReader.cpp
index dd93c5024e1..8bb1391f3e4 100644
--- a/Applications/Utils/FileConverter/GocadTSurfaceReader.cpp
+++ b/Applications/Utils/FileConverter/GocadTSurfaceReader.cpp
@@ -9,11 +9,8 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "Applications/FileIO/GocadIO/GocadAsciiReader.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
 #include "MeshLib/Mesh.h"
@@ -65,17 +62,12 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if (export_lines_arg.isSet() && export_surfaces_arg.isSet())
     {
         ERR("Both the 'lines-only'-flag and 'surfaces-only'-flag are set. Only "
             "one is allowed at a time.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 2;
     }
 
@@ -94,9 +86,6 @@ int main(int argc, char* argv[])
     if (!FileIO::Gocad::GocadAsciiReader::readFile(file_name, meshes, t))
     {
         ERR("Error reading file.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 1;
     }
     INFO("{:d} meshes found.", meshes.size());
@@ -115,8 +104,5 @@ int main(int argc, char* argv[])
         MeshLib::IO::VtuInterface vtu(mesh.get(), data_mode, compressed);
         vtu.writeToFile(dir + delim + mesh->getName() + ".vtu");
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return 0;
 }
diff --git a/Applications/Utils/FileConverter/Mesh2Raster.cpp b/Applications/Utils/FileConverter/Mesh2Raster.cpp
index 4e32f111d57..9b090554776 100644
--- a/Applications/Utils/FileConverter/Mesh2Raster.cpp
+++ b/Applications/Utils/FileConverter/Mesh2Raster.cpp
@@ -9,15 +9,12 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <filesystem>
 #include <fstream>
 #include <memory>
 #include <string>
 
+#include "BaseLib/MPI.h"
 #include "GeoLib/AABB.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -52,9 +49,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     INFO("Rasterising mesh...");
     std::unique_ptr<MeshLib::Mesh> const mesh(
@@ -62,18 +57,12 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         ERR("Error reading mesh file.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 1;
     }
     if (mesh->getDimension() != 2)
     {
         ERR("The programme requires a mesh containing two-dimensional elements "
             "(i.e. triangles or quadrilaterals.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 2;
     }
 
@@ -178,8 +167,5 @@ int main(int argc, char* argv[])
     }
     out.close();
     INFO("Result written to {:s}", output_name);
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return 0;
 }
diff --git a/Applications/Utils/FileConverter/Mesh2Shape.cpp b/Applications/Utils/FileConverter/Mesh2Shape.cpp
index b9ffd3f0493..44bb45b383b 100644
--- a/Applications/Utils/FileConverter/Mesh2Shape.cpp
+++ b/Applications/Utils/FileConverter/Mesh2Shape.cpp
@@ -9,11 +9,8 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "Applications/FileIO/SHPInterface.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/Mesh.h"
@@ -43,22 +40,14 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::string const file_name(input_arg.getValue());
     std::unique_ptr<MeshLib::Mesh> const mesh(
         MeshLib::IO::readMeshFromFile(file_name));
     if (FileIO::SHPInterface::write2dMeshToSHP(output_arg.getValue(), *mesh))
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_SUCCESS;
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_FAILURE;
 }
diff --git a/Applications/Utils/FileConverter/NetCdfConverter.cpp b/Applications/Utils/FileConverter/NetCdfConverter.cpp
index 84e3be1b7ab..8009dd19e5f 100644
--- a/Applications/Utils/FileConverter/NetCdfConverter.cpp
+++ b/Applications/Utils/FileConverter/NetCdfConverter.cpp
@@ -9,10 +9,6 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 // STL
 #include <cctype>
 #include <iostream>
@@ -26,6 +22,7 @@
 
 #include "BaseLib/FileTools.h"
 #include "BaseLib/Logging.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Raster.h"
 #include "InfoLib/GitInfo.h"
@@ -740,18 +737,13 @@ int main(int argc, char* argv[])
     cmd.add(arg_input);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     NcFile dataset(arg_input.getValue().c_str(), NcFile::read);
 
     if (dataset.isNull())
     {
         ERR("Error opening file.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 
@@ -761,9 +753,6 @@ int main(int argc, char* argv[])
     {
         ERR("Only one output format can be specified (single-file, multi-file, "
             "or images)");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -783,9 +772,6 @@ int main(int argc, char* argv[])
     if (var.isNull())
     {
         ERR("Variable \"{:s}\" not found in file.", arg_varname.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -797,9 +783,6 @@ int main(int argc, char* argv[])
         if (!assignDimParams(var, dim_idx_map, arg_dim_time, arg_dim1, arg_dim2,
                              arg_dim3))
         {
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
@@ -856,15 +839,9 @@ int main(int argc, char* argv[])
     if (!convert(dataset, var, output_name, dim_idx_map, is_time_dep,
                  time_bounds, output, elem_type))
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
     std::cout << "Conversion finished successfully.\n";
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/OGS2VTK.cpp b/Applications/Utils/FileConverter/OGS2VTK.cpp
index 78f360c2883..46bc603a270 100644
--- a/Applications/Utils/FileConverter/OGS2VTK.cpp
+++ b/Applications/Utils/FileConverter/OGS2VTK.cpp
@@ -13,13 +13,10 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <memory>
 #include <string>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -52,17 +49,12 @@ int main(int argc, char* argv[])
     cmd.add(use_ascii_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh const> mesh(
         MeshLib::IO::readMeshFromFile(mesh_in.getValue()));
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("Mesh read: {:d} nodes, {:d} elements.", mesh->getNumberOfNodes(),
@@ -73,8 +65,5 @@ int main(int argc, char* argv[])
 
     MeshLib::IO::writeVtu(*mesh, mesh_out.getValue(), data_mode);
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/PVD2XDMF.cpp b/Applications/Utils/FileConverter/PVD2XDMF.cpp
index 838aa202559..6c114ef6673 100644
--- a/Applications/Utils/FileConverter/PVD2XDMF.cpp
+++ b/Applications/Utils/FileConverter/PVD2XDMF.cpp
@@ -9,10 +9,6 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <array>
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/xml_parser.hpp>
@@ -20,6 +16,7 @@
 
 #include "BaseLib/FileTools.h"
 #include "BaseLib/Logging.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/MemWatch.h"
 #include "BaseLib/RunTime.h"
 #include "BaseLib/StringTools.h"
@@ -141,9 +138,7 @@ int main(int argc, char* argv[])
     cmd.add(outdir_arg);
 
     cmd.parse(argc, argv);
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
     BaseLib::setConsoleLogLevel(log_level_arg.getValue());
 
     auto const pvd_file_dir = BaseLib::extractPath(pvd_file_arg.getValue());
@@ -237,8 +232,5 @@ int main(int argc, char* argv[])
 
         mesh_xdmf_hdf_writer->writeStep(time);
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/Raster2ASC.cpp b/Applications/Utils/FileConverter/Raster2ASC.cpp
index de81adf7d19..398d8665c11 100644
--- a/Applications/Utils/FileConverter/Raster2ASC.cpp
+++ b/Applications/Utils/FileConverter/Raster2ASC.cpp
@@ -11,10 +11,7 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Raster.h"
 #include "InfoLib/GitInfo.h"
@@ -41,9 +38,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<GeoLib::Raster> raster(
         FileIO::AsciiRasterInterface::readRaster(input_arg.getValue()));
@@ -61,8 +56,5 @@ int main(int argc, char* argv[])
     }
 
     FileIO::AsciiRasterInterface::writeRasterAsASC(*raster, output_name);
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/TIN2VTK.cpp b/Applications/Utils/FileConverter/TIN2VTK.cpp
index 91cc0a1962b..1d2b7290baa 100644
--- a/Applications/Utils/FileConverter/TIN2VTK.cpp
+++ b/Applications/Utils/FileConverter/TIN2VTK.cpp
@@ -9,17 +9,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 // STL
 #include <memory>
 #include <string>
 #include <vector>
 
-// BaseLib
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 
 // GeoLib
@@ -53,9 +49,7 @@ int main(int argc, char* argv[])
     cmd.add(outArg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     INFO("reading the TIN file...");
     const std::string tinFileName(inArg.getValue());
@@ -66,9 +60,6 @@ int main(int argc, char* argv[])
         GeoLib::IO::TINInterface::readTIN(tinFileName, point_vec));
     if (!sfc)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("TIN read:  {:d} points, {:d} triangles", point_vec.size(),
@@ -85,8 +76,5 @@ int main(int argc, char* argv[])
     MeshLib::IO::VtuInterface writer(mesh.get());
     writer.writeToFile(outArg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/TecPlotTools.cpp b/Applications/Utils/FileConverter/TecPlotTools.cpp
index 0d70176cf19..bf209269396 100644
--- a/Applications/Utils/FileConverter/TecPlotTools.cpp
+++ b/Applications/Utils/FileConverter/TecPlotTools.cpp
@@ -9,16 +9,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <iostream>
 #include <memory>
 #include <string>
 #include <string_view>
 #include <vector>
 
+#include "BaseLib/MPI.h"
 #include "BaseLib/StringTools.h"
 #include "GeoLib/Point.h"
 #include "InfoLib/GitInfo.h"
@@ -480,25 +477,17 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if (!input_arg.isSet())
     {
         ERR("No input file given. Please specify TecPlot (*.plt) file");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 
     if (convert_arg.getValue() && !output_arg.isSet())
     {
         ERR("No output file given. Please specify OGS mesh (*.vtu) file");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 
@@ -506,18 +495,12 @@ int main(int argc, char* argv[])
     if (!in.is_open())
     {
         ERR("Could not open file {:s}.", input_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -2;
     }
 
     if (!convert_arg.isSet() && !split_arg.isSet())
     {
         INFO("Nothing to do. Use -s to split or -c to convert.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 0;
     }
 
@@ -534,8 +517,5 @@ int main(int argc, char* argv[])
     }
 
     in.close();
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return return_val;
 }
diff --git a/Applications/Utils/FileConverter/VTK2OGS.cpp b/Applications/Utils/FileConverter/VTK2OGS.cpp
index 2ec723dc2e7..80c424df8a1 100644
--- a/Applications/Utils/FileConverter/VTK2OGS.cpp
+++ b/Applications/Utils/FileConverter/VTK2OGS.cpp
@@ -14,12 +14,9 @@
 // STL
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <string>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/Legacy/MeshIO.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
@@ -47,9 +44,7 @@ int main(int argc, char* argv[])
     cmd.add(mesh_out);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     MeshLib::Mesh* mesh(
         MeshLib::IO::VtuInterface::readVTUFile(mesh_in.getValue()));
@@ -60,8 +55,5 @@ int main(int argc, char* argv[])
     meshIO.setMesh(mesh);
     BaseLib::IO::writeStringToFile(meshIO.writeToString(), mesh_out.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/VTK2TIN.cpp b/Applications/Utils/FileConverter/VTK2TIN.cpp
index b0401d1b199..bde167facc2 100644
--- a/Applications/Utils/FileConverter/VTK2TIN.cpp
+++ b/Applications/Utils/FileConverter/VTK2TIN.cpp
@@ -9,17 +9,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 // STL
 #include <fstream>
 #include <memory>
 #include <string>
 
-// BaseLib
 #include "BaseLib/Logging.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 
 // GeoLib
@@ -56,9 +52,7 @@ int main(int argc, char* argv[])
     cmd.add(mesh_out);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
     std::unique_ptr<MeshLib::Mesh> mesh(
         MeshLib::IO::VtuInterface::readVTUFile(mesh_in.getValue()));
     INFO("Mesh read: {:d} nodes, {:d} elements.", mesh->getNumberOfNodes(),
@@ -74,8 +68,5 @@ int main(int argc, char* argv[])
             mesh_out.getValue());
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/convertGEO.cpp b/Applications/Utils/FileConverter/convertGEO.cpp
index c7f76b7f641..3a7d859d519 100644
--- a/Applications/Utils/FileConverter/convertGEO.cpp
+++ b/Applications/Utils/FileConverter/convertGEO.cpp
@@ -10,15 +10,12 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <string>
 #include <vector>
 
 #include "Applications/FileIO/readGeometryFromFile.h"
 #include "Applications/FileIO/writeGeometryToFile.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "InfoLib/GitInfo.h"
 
@@ -51,9 +48,7 @@ int main(int argc, char* argv[])
     cmd.add(gmsh_path_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     GeoLib::GEOObjects geoObjects;
     FileIO::readGeometryFromFile(argInputFileName.getValue(), geoObjects,
@@ -64,8 +59,5 @@ int main(int argc, char* argv[])
     FileIO::writeGeometryToFile(geo_names[0], geoObjects,
                                 argOutputFileName.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/FileConverter/generateMatPropsFromMatID.cpp b/Applications/Utils/FileConverter/generateMatPropsFromMatID.cpp
index 9291eacb3b7..88032d6354e 100644
--- a/Applications/Utils/FileConverter/generateMatPropsFromMatID.cpp
+++ b/Applications/Utils/FileConverter/generateMatPropsFromMatID.cpp
@@ -14,14 +14,11 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <fstream>
 #include <memory>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -50,9 +47,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // read mesh
     std::unique_ptr<MeshLib::Mesh> mesh(
@@ -61,9 +56,6 @@ int main(int argc, char* argv[])
     if (!mesh)
     {
         INFO("Could not read mesh from file '{:s}'.", mesh_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -92,9 +84,6 @@ int main(int argc, char* argv[])
     else
     {
         ERR("Could not create property '{:s}' file.", new_matname);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -106,8 +95,5 @@ int main(int argc, char* argv[])
 
     INFO("New files '{:s}' and '{:s}' written.", new_mshname, new_matname);
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/GeoTools/MoveGeometry.cpp b/Applications/Utils/GeoTools/MoveGeometry.cpp
index 33505f1d594..dd14e7210d2 100644
--- a/Applications/Utils/GeoTools/MoveGeometry.cpp
+++ b/Applications/Utils/GeoTools/MoveGeometry.cpp
@@ -14,10 +14,7 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.h"
 #include "InfoLib/GitInfo.h"
@@ -49,9 +46,7 @@ int main(int argc, char* argv[])
     cmd.add(geo_input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     GeoLib::GEOObjects geo_objects;
     GeoLib::IO::BoostXmlGmlInterface xml(geo_objects);
@@ -59,9 +54,6 @@ int main(int argc, char* argv[])
     {
         if (!xml.readFile(geo_input_arg.getValue()))
         {
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
@@ -69,9 +61,6 @@ int main(int argc, char* argv[])
     {
         ERR("Failed to read file `{:s}'.", geo_input_arg.getValue());
         ERR("{:s}", err.what());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -106,8 +95,5 @@ int main(int argc, char* argv[])
     BaseLib::IO::writeStringToFile(xml.writeToString(),
                                    geo_output_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/GeoTools/addDataToRaster.cpp b/Applications/Utils/GeoTools/addDataToRaster.cpp
index 425bfb5d689..c78dc0549cc 100644
--- a/Applications/Utils/GeoTools/addDataToRaster.cpp
+++ b/Applications/Utils/GeoTools/addDataToRaster.cpp
@@ -11,16 +11,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <cmath>
 #include <memory>
 #include <numbers>
 #include <numeric>
 
+#include "BaseLib/MPI.h"
 #include "GeoLib/AABB.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Point.h"
@@ -153,9 +150,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::array input_points = {
         GeoLib::Point{{ll_x_arg.getValue(), ll_y_arg.getValue(), 0}},
@@ -210,8 +205,5 @@ int main(int argc, char* argv[])
 
     FileIO::AsciiRasterInterface::writeRasterAsASC(*raster,
                                                    out_raster_arg.getValue());
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/GeoTools/createRaster.cpp b/Applications/Utils/GeoTools/createRaster.cpp
index 8d36fc335aa..b3aa8b4b8f0 100644
--- a/Applications/Utils/GeoTools/createRaster.cpp
+++ b/Applications/Utils/GeoTools/createRaster.cpp
@@ -11,12 +11,9 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <memory>
 
+#include "BaseLib/MPI.h"
 #include "GeoLib/AABB.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Point.h"
@@ -71,9 +68,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     GeoLib::RasterHeader header{
         n_cols.getValue(),
@@ -88,8 +83,5 @@ int main(int argc, char* argv[])
     FileIO::AsciiRasterInterface::writeRasterAsASC(raster,
                                                    output_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/GeoTools/generateGeometry.cpp b/Applications/Utils/GeoTools/generateGeometry.cpp
index b84b167e37f..56c054e79e0 100644
--- a/Applications/Utils/GeoTools/generateGeometry.cpp
+++ b/Applications/Utils/GeoTools/generateGeometry.cpp
@@ -11,12 +11,9 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <numeric>
 
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.h"
 #include "GeoLib/Point.h"
@@ -241,9 +238,7 @@ int main(int argc, char* argv[])
     cmd.add(geo_output_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     auto const p0 = GeoLib::Point{x0.getValue(), y0.getValue(), z0.getValue()};
     auto const p1 = GeoLib::Point{x1.getValue(), y1.getValue(), z1.getValue()};
@@ -286,9 +281,6 @@ int main(int argc, char* argv[])
                 std::move(polyline_name.getValue()), geometry_name.getValue(),
                 geometry) == EXIT_FAILURE)
         {
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
@@ -298,8 +290,5 @@ int main(int argc, char* argv[])
     BaseLib::IO::writeStringToFile(xml.writeToString(),
                                    geo_output_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/AddElementQuality.cpp b/Applications/Utils/MeshEdit/AddElementQuality.cpp
index 25753925c28..08c7087db3b 100644
--- a/Applications/Utils/MeshEdit/AddElementQuality.cpp
+++ b/Applications/Utils/MeshEdit/AddElementQuality.cpp
@@ -9,13 +9,10 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <array>
 #include <string>
 
+#include "BaseLib/MPI.h"
 #include "BaseLib/RunTime.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -53,9 +50,7 @@ int main(int argc, char* argv[])
     cmd.add(mesh_in_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // read the mesh file
     BaseLib::RunTime run_time;
@@ -64,9 +59,6 @@ int main(int argc, char* argv[])
         mesh_in_arg.getValue(), true /* compute_element_neighbors */));
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("Time for reading: {:g} s", run_time.elapsed());
@@ -82,8 +74,5 @@ int main(int argc, char* argv[])
     INFO("Writing mesh '{:s}' ... ", mesh_out_arg.getValue());
     MeshLib::IO::writeMeshToFile(*mesh, mesh_out_arg.getValue());
     INFO("done.");
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/AddFaultToVoxelGrid.cpp b/Applications/Utils/MeshEdit/AddFaultToVoxelGrid.cpp
index e27be76f846..2d4e47d92a5 100644
--- a/Applications/Utils/MeshEdit/AddFaultToVoxelGrid.cpp
+++ b/Applications/Utils/MeshEdit/AddFaultToVoxelGrid.cpp
@@ -15,10 +15,7 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -64,9 +61,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::string const input_name = input_arg.getValue();
     std::string const fault_name = fault_arg.getValue();
@@ -81,17 +76,11 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         ERR("Input mesh not found...");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     auto const& mat_ids = MeshLib::materialIDs(*mesh);
     if (!mat_ids)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         ERR("Input mesh has no material IDs");
         return EXIT_FAILURE;
     }
@@ -105,15 +94,9 @@ int main(int argc, char* argv[])
     {
         MeshLib::IO::VtuInterface vtu(mesh.get());
         vtu.writeToFile(output_name);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         INFO("The fault was successfully added.");
         return EXIT_SUCCESS;
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     ERR("No fault could be added.");
     return EXIT_FAILURE;
 }
diff --git a/Applications/Utils/MeshEdit/AddLayer.cpp b/Applications/Utils/MeshEdit/AddLayer.cpp
index 7958e404e2d..90e2d51efb7 100644
--- a/Applications/Utils/MeshEdit/AddLayer.cpp
+++ b/Applications/Utils/MeshEdit/AddLayer.cpp
@@ -11,13 +11,10 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <memory>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -78,15 +75,10 @@ int main(int argc, char* argv[])
     {
         ERR("It is not possible to set both options '--copy-material-ids' and "
             "'--set-material-id'.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     INFO("Reading mesh '{:s}' ... ", mesh_arg.getValue());
     auto subsfc_mesh = std::unique_ptr<MeshLib::Mesh>(
@@ -94,9 +86,6 @@ int main(int argc, char* argv[])
     if (!subsfc_mesh)
     {
         ERR("Error reading mesh '{:s}'.", mesh_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("done.");
@@ -114,9 +103,6 @@ int main(int argc, char* argv[])
     if (!result)
     {
         ERR("Failure while adding layer.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -124,8 +110,5 @@ int main(int argc, char* argv[])
     MeshLib::IO::writeMeshToFile(*result, mesh_out_arg.getValue());
     INFO("done.");
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/CreateBoundaryConditionsAlongPolylines.cpp b/Applications/Utils/MeshEdit/CreateBoundaryConditionsAlongPolylines.cpp
index 070bcedc532..1debc20fb54 100644
--- a/Applications/Utils/MeshEdit/CreateBoundaryConditionsAlongPolylines.cpp
+++ b/Applications/Utils/MeshEdit/CreateBoundaryConditionsAlongPolylines.cpp
@@ -12,10 +12,6 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <fstream>
 #include <map>
 #include <string>
@@ -24,6 +20,7 @@
 #include "Applications/FileIO/readGeometryFromFile.h"
 #include "Applications/FileIO/writeGeometryToFile.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/Point.h"
 #include "InfoLib/GitInfo.h"
@@ -183,9 +180,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // *** read mesh
     INFO("Reading mesh '{:s}' ... ", mesh_arg.getValue());
@@ -216,9 +211,6 @@ int main(int argc, char* argv[])
     {
         ERR("Could not get vector of polylines out of geometry '{:s}'.",
             geo_name);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -251,9 +243,6 @@ int main(int argc, char* argv[])
     if (geo_names.empty())
     {
         ERR("Did not find mesh nodes along polylines.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -313,8 +302,5 @@ int main(int argc, char* argv[])
         BaseLib::dropFileExtension(output_base_fname.getValue()));
     writeBCsAndGeometry(geometry_sets, surface_name, base_fname,
                         bc_type.getValue(), gml_arg.getValue());
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/ExtractBoundary.cpp b/Applications/Utils/MeshEdit/ExtractBoundary.cpp
index 744929e8c64..f643dbd7d10 100644
--- a/Applications/Utils/MeshEdit/ExtractBoundary.cpp
+++ b/Applications/Utils/MeshEdit/ExtractBoundary.cpp
@@ -11,16 +11,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <memory>
 #include <string>
 #include <vector>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/StringTools.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
@@ -63,18 +60,13 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh const> mesh(MeshLib::IO::readMeshFromFile(
         mesh_in.getValue(), true /* compute_element_neighbors */));
 
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -102,8 +94,5 @@ int main(int argc, char* argv[])
         use_ascii_arg.getValue() ? vtkXMLWriter::Ascii : vtkXMLWriter::Binary;
     MeshLib::IO::writeVtu(*surface_mesh, out_fname, data_mode);
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/ExtractMaterials.cpp b/Applications/Utils/MeshEdit/ExtractMaterials.cpp
index 9edf690aae1..050cf13656a 100644
--- a/Applications/Utils/MeshEdit/ExtractMaterials.cpp
+++ b/Applications/Utils/MeshEdit/ExtractMaterials.cpp
@@ -12,11 +12,8 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -73,9 +70,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::string const input_name = input_arg.getValue();
     std::string const output_name = output_arg.getValue();
@@ -87,9 +82,6 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         ERR("Error reading input mesh. Aborting...");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -97,9 +89,6 @@ int main(int argc, char* argv[])
     if (mat_ids == nullptr)
     {
         ERR("No material IDs found in mesh. Aborting...");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -107,9 +96,6 @@ int main(int argc, char* argv[])
     if (id_range.first == id_range.second)
     {
         ERR("Mesh only contains one material, no extraction required.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     int min_id, max_id;
@@ -119,9 +105,6 @@ int main(int argc, char* argv[])
         if (min_id < *id_range.first || min_id > *id_range.second)
         {
             ERR("Specified material ID does not exist.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
         max_id = min_id;
@@ -160,8 +143,5 @@ int main(int argc, char* argv[])
     {
         ostream.close();
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/ExtractSurface.cpp b/Applications/Utils/MeshEdit/ExtractSurface.cpp
index da959739497..f8a95e304de 100644
--- a/Applications/Utils/MeshEdit/ExtractSurface.cpp
+++ b/Applications/Utils/MeshEdit/ExtractSurface.cpp
@@ -11,16 +11,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <memory>
 #include <string>
 #include <vector>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/StringTools.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
@@ -75,9 +72,7 @@ int main(int argc, char* argv[])
     cmd.add(mesh_in);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh const> mesh(MeshLib::IO::readMeshFromFile(
         mesh_in.getValue(), true /* compute_element_neighbors */));
@@ -85,18 +80,12 @@ int main(int argc, char* argv[])
     if (!mesh)
     {
         ERR("Error reading mesh file.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
     if (mesh->getDimension() != 3)
     {
         ERR("Surfaces can currently only be extracted from 3D meshes.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -122,8 +111,5 @@ int main(int argc, char* argv[])
         use_ascii_arg.getValue() ? vtkXMLWriter::Ascii : vtkXMLWriter::Binary;
     MeshLib::IO::writeVtu(*surface_mesh, out_fname, data_mode);
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/Layers2Grid.cpp b/Applications/Utils/MeshEdit/Layers2Grid.cpp
index 6108bee99fd..12525d1326c 100644
--- a/Applications/Utils/MeshEdit/Layers2Grid.cpp
+++ b/Applications/Utils/MeshEdit/Layers2Grid.cpp
@@ -15,11 +15,8 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "BaseLib/IO/readStringListFromFile.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/AABB.h"
 #include "InfoLib/GitInfo.h"
 #include "MathLib/Point3d.h"
@@ -78,18 +75,13 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if ((y_arg.isSet() && !z_arg.isSet()) ||
         ((!y_arg.isSet() && z_arg.isSet())))
     {
         ERR("For equilateral cubes, only x needs to be set. For unequal "
             "cuboids, all three edge lengths (x/y/z) need to be specified.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -104,9 +96,6 @@ int main(int argc, char* argv[])
     if (layer_names.size() < 2)
     {
         ERR("At least two layers are required to create a 3D Mesh");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -124,9 +113,6 @@ int main(int argc, char* argv[])
         if (mesh == nullptr)
         {
             ERR("Input layer '{:s}' not found. Aborting...", layer);
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
         layers.emplace_back(mesh);
@@ -141,15 +127,9 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         ERR("The VoxelGrid could not be created.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     MeshLib::IO::VtuInterface vtu(mesh.get());
     vtu.writeToFile(output_name);
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/MapGeometryToMeshSurface.cpp b/Applications/Utils/MeshEdit/MapGeometryToMeshSurface.cpp
index d32118f004c..106e8305d44 100644
--- a/Applications/Utils/MeshEdit/MapGeometryToMeshSurface.cpp
+++ b/Applications/Utils/MeshEdit/MapGeometryToMeshSurface.cpp
@@ -11,14 +11,11 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <cstdlib>
 #include <vector>
 
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.h"
 #include "InfoLib/GitInfo.h"
@@ -60,9 +57,7 @@ int main(int argc, char* argv[])
     cmd.add(output_geometry_fname);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // *** read geometry
     GeoLib::GEOObjects geometries;
@@ -75,9 +70,6 @@ int main(int argc, char* argv[])
         }
         else
         {
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
@@ -105,8 +97,5 @@ int main(int argc, char* argv[])
         BaseLib::IO::writeStringToFile(xml_io.writeToString(),
                                        output_geometry_fname.getValue());
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/MeshMapping.cpp b/Applications/Utils/MeshEdit/MeshMapping.cpp
index 6b939c1821d..3d3f3139fda 100644
--- a/Applications/Utils/MeshEdit/MeshMapping.cpp
+++ b/Applications/Utils/MeshEdit/MeshMapping.cpp
@@ -15,11 +15,8 @@
 #include <memory>
 #include <string>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/AABB.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Raster.h"
@@ -54,9 +51,7 @@ double getClosestPointElevation(MeshLib::Node const& p,
 
 int main(int argc, char* argv[])
 {
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
     TCLAP::CmdLine cmd(
         "Changes the elevation of 2D mesh nodes based on either raster data or "
         "another 2D mesh. In addition, a low pass filter can be applied to "
@@ -107,9 +102,6 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         ERR("Error reading mesh file.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -118,18 +110,12 @@ int main(int argc, char* argv[])
     {
         ERR("Nothing to do. Please choose mapping based on a raster or mesh "
             "file, or to a static value.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
     if (map_raster_arg.isSet() && map_mesh_arg.isSet())
     {
         ERR("Please select mapping based on *either* a mesh or a raster file.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -148,9 +134,6 @@ int main(int argc, char* argv[])
         if (!file_stream.good())
         {
             ERR("Opening raster file {} failed.", raster_path);
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
         file_stream.close();
@@ -168,9 +151,6 @@ int main(int argc, char* argv[])
         if (ground_truth == nullptr)
         {
             ERR("Error reading mesh file.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
 
@@ -243,15 +223,9 @@ int main(int argc, char* argv[])
 
     if (MeshLib::IO::writeMeshToFile(*mesh, output_arg.getValue()) != 0)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
     INFO("Result successfully written.");
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/MoveMesh.cpp b/Applications/Utils/MeshEdit/MoveMesh.cpp
index a755a792143..65cefe2c3bb 100644
--- a/Applications/Utils/MeshEdit/MoveMesh.cpp
+++ b/Applications/Utils/MeshEdit/MoveMesh.cpp
@@ -11,11 +11,8 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/StringTools.h"
 #include "GeoLib/AABB.h"
 #include "InfoLib/GitInfo.h"
@@ -64,9 +61,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
     std::string fname(mesh_arg.getValue());
 
     std::unique_ptr<MeshLib::Mesh> mesh(MeshLib::IO::readMeshFromFile(fname));
@@ -74,9 +69,6 @@ int main(int argc, char* argv[])
     if (!mesh)
     {
         ERR("Could not read mesh from file '{:s}'.", fname);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -107,8 +99,5 @@ int main(int argc, char* argv[])
 
     MeshLib::IO::writeMeshToFile(*mesh, out_fname);
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/NodeReordering.cpp b/Applications/Utils/MeshEdit/NodeReordering.cpp
index cc83457c3a4..f98f0063975 100644
--- a/Applications/Utils/MeshEdit/NodeReordering.cpp
+++ b/Applications/Utils/MeshEdit/NodeReordering.cpp
@@ -11,16 +11,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <array>
 #include <memory>
 #include <vector>
 
 #include "BaseLib/Algorithm.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -191,18 +188,13 @@ int main(int argc, char* argv[])
     cmd.add(input_mesh_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh> mesh(
         MeshLib::IO::readMeshFromFile(input_mesh_arg.getValue()));
 
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -228,8 +220,5 @@ int main(int argc, char* argv[])
 
     INFO("VTU file written.");
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/PVTU2VTU/PVTU2VTU.cpp b/Applications/Utils/MeshEdit/PVTU2VTU/PVTU2VTU.cpp
index 0073291797d..753004bf2bc 100644
--- a/Applications/Utils/MeshEdit/PVTU2VTU/PVTU2VTU.cpp
+++ b/Applications/Utils/MeshEdit/PVTU2VTU/PVTU2VTU.cpp
@@ -24,11 +24,8 @@
 #include <unordered_set>
 #include <vector>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/RunTime.h"
 #include "GeoLib/AABB.h"
 #include "GeoLib/OctTree.h"
@@ -390,9 +387,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if (BaseLib::getFileExtension(input_arg.getValue()) != ".pvtu")
     {
@@ -502,9 +497,6 @@ int main(int argc, char* argv[])
     if (!result)
     {
         ERR("Could not write mesh to '{:s}'.", output_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("writing mesh took {} s", writing_timer.elapsed());
@@ -516,8 +508,5 @@ int main(int argc, char* argv[])
     // cleaned.
     merged_mesh.shallowClean();
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/RemoveGhostData.cpp b/Applications/Utils/MeshEdit/RemoveGhostData.cpp
index 1824b8661c7..1384ac736b2 100644
--- a/Applications/Utils/MeshEdit/RemoveGhostData.cpp
+++ b/Applications/Utils/MeshEdit/RemoveGhostData.cpp
@@ -15,11 +15,8 @@
 #include <vtkXMLPUnstructuredGridReader.h>
 #include <vtkXMLUnstructuredGridWriter.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "BaseLib/Logging.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/writeMeshToFile.h"
 
@@ -51,9 +48,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     vtkSmartPointer<vtkXMLPUnstructuredGridReader> reader =
         vtkSmartPointer<vtkXMLPUnstructuredGridReader>::New();
@@ -73,8 +68,5 @@ int main(int argc, char* argv[])
     writer->SetFileName(output_arg.getValue().c_str());
     writer->Write();
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/ReorderMesh.cpp b/Applications/Utils/MeshEdit/ReorderMesh.cpp
index fd5334d5ee1..5de0c9879c8 100644
--- a/Applications/Utils/MeshEdit/ReorderMesh.cpp
+++ b/Applications/Utils/MeshEdit/ReorderMesh.cpp
@@ -12,10 +12,7 @@
 #include <memory>
 #include <string>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -136,9 +133,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     const std::string filename(mesh_in_arg.getValue());
 
@@ -147,9 +142,6 @@ int main(int argc, char* argv[])
         std::unique_ptr<MeshLib::Mesh>(MeshLib::IO::readMeshFromFile(filename));
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -247,8 +239,5 @@ int main(int argc, char* argv[])
             "transferred to the reordered mesh.");
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/ResetPropertiesInPolygonalRegion.cpp b/Applications/Utils/MeshEdit/ResetPropertiesInPolygonalRegion.cpp
index 76631d3ea97..ada2f29b6dd 100644
--- a/Applications/Utils/MeshEdit/ResetPropertiesInPolygonalRegion.cpp
+++ b/Applications/Utils/MeshEdit/ResetPropertiesInPolygonalRegion.cpp
@@ -16,11 +16,8 @@
 #include <cstdlib>
 #include <vector>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "Applications/FileIO/readGeometryFromFile.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/Polygon.h"
 #include "InfoLib/GitInfo.h"
@@ -99,9 +96,7 @@ int main(int argc, char* argv[])
     cmd.add(gmsh_path_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // *** read geometry
     GeoLib::GEOObjects geometries;
@@ -117,9 +112,6 @@ int main(int argc, char* argv[])
     {
         ERR("Could not get vector of polylines out of geometry '{:s}'.",
             geo_name);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -129,9 +121,6 @@ int main(int argc, char* argv[])
     if (!ply)
     {
         ERR("Polyline '{:s}' not found.", polygon_name_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -140,9 +129,6 @@ int main(int argc, char* argv[])
     {
         ERR("Polyline '{:s}' is not closed, i.e. does not describe a region.",
             polygon_name_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -154,9 +140,6 @@ int main(int argc, char* argv[])
     if (!mesh)
     {
         // error message written already by readMeshFromFile
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     std::string const& property_name(property_name_arg.getValue());
@@ -186,8 +169,5 @@ int main(int argc, char* argv[])
 
     MeshLib::IO::writeMeshToFile(*mesh, mesh_out.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/Vtu2Grid.cpp b/Applications/Utils/MeshEdit/Vtu2Grid.cpp
index 7429e1d9f72..55a8bc6f582 100644
--- a/Applications/Utils/MeshEdit/Vtu2Grid.cpp
+++ b/Applications/Utils/MeshEdit/Vtu2Grid.cpp
@@ -10,6 +10,7 @@
 #include <tclap/CmdLine.h>
 #include <vtkXMLUnstructuredGridReader.h>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/writeMeshToFile.h"
 #include "MeshLib/Mesh.h"
@@ -18,9 +19,6 @@
 #include "MeshToolsLib/MeshGenerators/MeshGenerator.h"
 #include "MeshToolsLib/MeshGenerators/VoxelGridFromMesh.h"
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
 int main(int argc, char* argv[])
 {
     TCLAP::CmdLine cmd(
@@ -64,18 +62,13 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if ((y_arg.isSet() && !z_arg.isSet()) ||
         ((!y_arg.isSet() && z_arg.isSet())))
     {
         ERR("For equilateral cubes, only x needs to be set. For unequal "
             "cuboids, all three edge lengths (x/y/z) need to be specified.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
     using namespace MeshToolsLib::MeshGenerator;
@@ -88,9 +81,6 @@ int main(int argc, char* argv[])
     {
         ERR("A cellsize ({},{},{}) is not allowed to be <= 0", x_size, y_size,
             z_size);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 
@@ -113,9 +103,6 @@ int main(int argc, char* argv[])
     {
         ERR("The range ({},{},{}) is not allowed to be < 0", ranges[0],
             ranges[1], ranges[2]);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
     std::array<std::size_t, 3> const dims =
@@ -134,9 +121,6 @@ int main(int argc, char* argv[])
 
     if (!VoxelGridFromMesh::removeUnusedGridCells(mesh, grid))
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -144,14 +128,8 @@ int main(int argc, char* argv[])
 
     if (MeshLib::IO::writeMeshToFile(*grid, output_arg.getValue()) != 0)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/appendLinesAlongPolyline.cpp b/Applications/Utils/MeshEdit/appendLinesAlongPolyline.cpp
index e7ab944bd29..69e3baa1522 100644
--- a/Applications/Utils/MeshEdit/appendLinesAlongPolyline.cpp
+++ b/Applications/Utils/MeshEdit/appendLinesAlongPolyline.cpp
@@ -11,12 +11,9 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "Applications/FileIO/readGeometryFromFile.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/PolylineVec.h"
 #include "InfoLib/GitInfo.h"
@@ -58,9 +55,7 @@ int main(int argc, char* argv[])
     // parse arguments
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // read GEO objects
     GeoLib::GEOObjects geo_objs;
@@ -71,9 +66,6 @@ int main(int argc, char* argv[])
     if (geo_names.empty())
     {
         ERR("No geometries found.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     const GeoLib::PolylineVec* ply_vec(
@@ -81,9 +73,6 @@ int main(int argc, char* argv[])
     if (!ply_vec)
     {
         ERR("Could not find polylines in geometry '{:s}'.", geo_names.front());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -93,9 +82,6 @@ int main(int argc, char* argv[])
     if (!mesh)
     {
         ERR("Mesh file '{:s}' not found", mesh_in.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("Mesh read: {:d} nodes, {:d} elements.", mesh->getNumberOfNodes(),
@@ -109,8 +95,5 @@ int main(int argc, char* argv[])
 
     MeshLib::IO::writeMeshToFile(*new_mesh, mesh_out.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/checkMesh.cpp b/Applications/Utils/MeshEdit/checkMesh.cpp
index 4795937702c..2d31816fd60 100644
--- a/Applications/Utils/MeshEdit/checkMesh.cpp
+++ b/Applications/Utils/MeshEdit/checkMesh.cpp
@@ -7,18 +7,14 @@
  *              http://www.opengeosys.org/project/license
  */
 
-#include <tclap/CmdLine.h>
-
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <spdlog/fmt/bundled/ranges.h>
+#include <tclap/CmdLine.h>
 
 #include <array>
 #include <string>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/MemWatch.h"
 #include "BaseLib/RunTime.h"
 #include "BaseLib/StringTools.h"
@@ -52,9 +48,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // read the mesh file
     BaseLib::MemWatch mem_watch;
@@ -65,9 +59,6 @@ int main(int argc, char* argv[])
         mesh_arg.getValue(), true /* compute_element_neighbors */));
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -106,8 +97,5 @@ int main(int argc, char* argv[])
         // Remark: MeshValidation can modify the original mesh
         MeshToolsLib::MeshInformation::writeMeshValidationResults(*mesh);
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/convertToLinearMesh.cpp b/Applications/Utils/MeshEdit/convertToLinearMesh.cpp
index 2eeea03f024..61569eaaba6 100644
--- a/Applications/Utils/MeshEdit/convertToLinearMesh.cpp
+++ b/Applications/Utils/MeshEdit/convertToLinearMesh.cpp
@@ -11,13 +11,10 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <memory>
 #include <string>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -42,25 +39,17 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh> mesh(
         MeshLib::IO::readMeshFromFile(input_arg.getValue()));
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     if (!mesh->hasNonlinearElement())
     {
         ERR("The input mesh is linear. Exit.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -71,8 +60,5 @@ int main(int argc, char* argv[])
     INFO("Save the new mesh into a file");
     MeshLib::IO::writeMeshToFile(*new_mesh, output_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/createLayeredMeshFromRasters.cpp b/Applications/Utils/MeshEdit/createLayeredMeshFromRasters.cpp
index 91ab223b4bc..56805e54f94 100644
--- a/Applications/Utils/MeshEdit/createLayeredMeshFromRasters.cpp
+++ b/Applications/Utils/MeshEdit/createLayeredMeshFromRasters.cpp
@@ -18,12 +18,9 @@
 #include <string>
 #include <vector>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "BaseLib/FileTools.h"
 #include "BaseLib/IO/readStringListFromFile.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
@@ -79,9 +76,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if (min_thickness_arg.isSet())
     {
@@ -89,9 +84,6 @@ int main(int argc, char* argv[])
         if (min_thickness < 0)
         {
             ERR("Minimum layer thickness must be non-negative value.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
@@ -102,17 +94,11 @@ int main(int argc, char* argv[])
     if (!sfc_mesh)
     {
         ERR("Error reading mesh '{:s}'.", mesh_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     if (sfc_mesh->getDimension() != 2)
     {
         ERR("Input mesh must be a 2D mesh.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("done.");
@@ -122,9 +108,6 @@ int main(int argc, char* argv[])
     if (raster_paths.size() < 2)
     {
         ERR("At least two raster files needed to create 3D mesh.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     std::reverse(raster_paths.begin(), raster_paths.end());
@@ -134,18 +117,12 @@ int main(int argc, char* argv[])
     {
         if (!mapper.createLayers(*sfc_mesh, *rasters, min_thickness))
         {
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
     else
     {
         ERR("Reading raster files.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -160,9 +137,6 @@ int main(int argc, char* argv[])
     if (result_mesh == nullptr)
     {
         ERR("Mapper returned empty result for 'SubsurfaceMesh'.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -172,8 +146,5 @@ int main(int argc, char* argv[])
     MeshLib::IO::writeVtu(*result_mesh, output_name, data_mode);
     INFO("done.");
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/createQuadraticMesh.cpp b/Applications/Utils/MeshEdit/createQuadraticMesh.cpp
index 735c37537c4..6758cf37146 100644
--- a/Applications/Utils/MeshEdit/createQuadraticMesh.cpp
+++ b/Applications/Utils/MeshEdit/createQuadraticMesh.cpp
@@ -9,13 +9,10 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <memory>
 #include <string>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -44,17 +41,12 @@ int main(int argc, char* argv[])
     cmd.add(add_centre_node_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh> mesh(
         MeshLib::IO::readMeshFromFile(input_arg.getValue()));
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -65,8 +57,5 @@ int main(int argc, char* argv[])
     INFO("Save the new mesh into a file");
     MeshLib::IO::writeMeshToFile(*new_mesh, output_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/createTetgenSmeshFromRasters.cpp b/Applications/Utils/MeshEdit/createTetgenSmeshFromRasters.cpp
index 838eb9bde55..4b2a881ff69 100644
--- a/Applications/Utils/MeshEdit/createTetgenSmeshFromRasters.cpp
+++ b/Applications/Utils/MeshEdit/createTetgenSmeshFromRasters.cpp
@@ -18,13 +18,10 @@
 #include <string>
 #include <vector>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "Applications/FileIO/TetGenInterface.h"
 #include "BaseLib/FileTools.h"
 #include "BaseLib/IO/readStringListFromFile.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
@@ -85,9 +82,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if (min_thickness_arg.isSet())
     {
@@ -95,9 +90,6 @@ int main(int argc, char* argv[])
         if (min_thickness < 0)
         {
             ERR("Minimum layer thickness must be non-negative value.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
@@ -108,17 +100,11 @@ int main(int argc, char* argv[])
     if (!sfc_mesh)
     {
         ERR("Error reading mesh '{:s}'.", mesh_arg.getValue());
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     if (sfc_mesh->getDimension() != 2)
     {
         ERR("Input mesh must be a 2D mesh.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("done.");
@@ -128,9 +114,6 @@ int main(int argc, char* argv[])
     if (raster_paths.size() < 2)
     {
         ERR("At least two raster files needed to create 3D mesh.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     std::reverse(raster_paths.begin(), raster_paths.end());
@@ -148,18 +131,12 @@ int main(int argc, char* argv[])
         if (!lv.createLayers(*sfc_mesh, *rasters, min_thickness))
         {
             ERR("Creating the layers was erroneous.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
     else
     {
         ERR("The raster files are not accessible.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     std::unique_ptr<MeshLib::Mesh> tg_mesh =
@@ -174,14 +151,8 @@ int main(int argc, char* argv[])
     else
     {
         ERR("The tetgen-smesh could not be created.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/editMaterialID.cpp b/Applications/Utils/MeshEdit/editMaterialID.cpp
index 17999779690..61d0892de46 100644
--- a/Applications/Utils/MeshEdit/editMaterialID.cpp
+++ b/Applications/Utils/MeshEdit/editMaterialID.cpp
@@ -9,12 +9,9 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <memory>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -68,24 +65,16 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if (!replaceArg.isSet() && !condenseArg.isSet() && !specifyArg.isSet())
     {
         INFO("Please select editing mode: -r or -c or -s");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 0;
     }
     if (replaceArg.isSet() && condenseArg.isSet())
     {
         INFO("Please select only one editing mode: -r or -c or -s");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 0;
     }
     if (replaceArg.isSet())
@@ -95,9 +84,6 @@ int main(int argc, char* argv[])
             INFO(
                 "current and new material IDs must be provided for "
                 "replacement");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return 0;
         }
     }
@@ -108,9 +94,6 @@ int main(int argc, char* argv[])
             INFO(
                 "element type and new material IDs must be provided to specify "
                 "elements");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return 0;
         }
     }
@@ -170,8 +153,5 @@ int main(int argc, char* argv[])
     }
     MeshLib::IO::writeMeshToFile(*mesh, mesh_out.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/ipDataToPointCloud.cpp b/Applications/Utils/MeshEdit/ipDataToPointCloud.cpp
index a8a2600b640..d1fda1f1f9d 100644
--- a/Applications/Utils/MeshEdit/ipDataToPointCloud.cpp
+++ b/Applications/Utils/MeshEdit/ipDataToPointCloud.cpp
@@ -11,10 +11,7 @@
 
 #include <unordered_map>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -255,9 +252,7 @@ int main(int argc, char** argv)
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh const> mesh_in(
         MeshLib::IO::readMeshFromFile(arg_in_file.getValue()));
@@ -273,8 +268,5 @@ int main(int argc, char** argv)
 
     MeshLib::IO::writeMeshToFile(point_cloud, arg_out_file.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/queryMesh.cpp b/Applications/Utils/MeshEdit/queryMesh.cpp
index fd713e8fe74..c4a3cb9d3e0 100644
--- a/Applications/Utils/MeshEdit/queryMesh.cpp
+++ b/Applications/Utils/MeshEdit/queryMesh.cpp
@@ -9,16 +9,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <array>
 #include <memory>
 #include <sstream>
 #include <string>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/StringTools.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
@@ -52,9 +49,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     const std::string filename(mesh_arg.getValue());
 
@@ -64,9 +59,6 @@ int main(int argc, char* argv[])
             filename, true /* compute_element_neighbors */));
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -155,8 +147,5 @@ int main(int argc, char* argv[])
         out << std::endl;
         INFO("{:s}", out.str());
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/removeMeshElements.cpp b/Applications/Utils/MeshEdit/removeMeshElements.cpp
index 456fe2635f1..bd20620b226 100644
--- a/Applications/Utils/MeshEdit/removeMeshElements.cpp
+++ b/Applications/Utils/MeshEdit/removeMeshElements.cpp
@@ -13,12 +13,9 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <memory>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -182,17 +179,12 @@ int main(int argc, char* argv[])
     cmd.add(mesh_in);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh const> mesh(
         MeshLib::IO::readMeshFromFile(mesh_in.getValue()));
     if (mesh == nullptr)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -229,9 +221,6 @@ int main(int argc, char* argv[])
             !property_name_arg.isSet())
         {
             ERR("Specify a property name for the value/range selected.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
 
@@ -241,9 +230,6 @@ int main(int argc, char* argv[])
         {
             ERR("Specify a value or range ('-min-value' and '-max_value') for "
                 "the property selected.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
 
@@ -264,9 +250,6 @@ int main(int argc, char* argv[])
             {
                 ERR("Specify if the inside or the outside of the selected "
                     "range should be removed.");
-#ifdef USE_PETSC
-                MPI_Finalize();
-#endif
                 return EXIT_FAILURE;
             }
 
@@ -299,9 +282,6 @@ int main(int argc, char* argv[])
         }
         if (aabb_error)
         {
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
 
@@ -324,17 +304,11 @@ int main(int argc, char* argv[])
 
     if (new_mesh == nullptr)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
     // write into a file
     MeshLib::IO::writeMeshToFile(*new_mesh, mesh_out.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/reviseMesh.cpp b/Applications/Utils/MeshEdit/reviseMesh.cpp
index ff9c0d3509a..ca06a00b084 100644
--- a/Applications/Utils/MeshEdit/reviseMesh.cpp
+++ b/Applications/Utils/MeshEdit/reviseMesh.cpp
@@ -9,15 +9,12 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <array>
 #include <memory>
 #include <string>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/StringTools.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
@@ -59,18 +56,13 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // read a mesh file
     std::unique_ptr<MeshLib::Mesh> org_mesh(
         MeshLib::IO::readMeshFromFile(input_arg.getValue()));
     if (!org_mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     INFO("Mesh read: {:d} nodes, {:d} elements.", org_mesh->getNumberOfNodes(),
@@ -92,8 +84,5 @@ int main(int argc, char* argv[])
         MeshLib::IO::writeMeshToFile(*new_mesh, output_arg.getValue());
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshEdit/swapNodeCoordinateAxes.cpp b/Applications/Utils/MeshEdit/swapNodeCoordinateAxes.cpp
index dcc9558a7f1..0eaadc7013e 100644
--- a/Applications/Utils/MeshEdit/swapNodeCoordinateAxes.cpp
+++ b/Applications/Utils/MeshEdit/swapNodeCoordinateAxes.cpp
@@ -9,15 +9,12 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <array>
 #include <memory>
 #include <string>
 
 #include "BaseLib/Logging.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -114,17 +111,12 @@ int main(int argc, char* argv[])
     cmd.add(new_order_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     const std::string str_order = new_order_arg.getValue();
     std::array<int, 3> new_order = {{}};
     if (!parseNewOrder(str_order, new_order))
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -132,9 +124,6 @@ int main(int argc, char* argv[])
         MeshLib::IO::readMeshFromFile(input_arg.getValue()));
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -152,8 +141,5 @@ int main(int argc, char* argv[])
     INFO("Save the new mesh into a file");
     MeshLib::IO::writeMeshToFile(*mesh, output_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/AssignRasterDataToMesh.cpp b/Applications/Utils/MeshGeoTools/AssignRasterDataToMesh.cpp
index ceada5695ec..338354d0d6e 100644
--- a/Applications/Utils/MeshGeoTools/AssignRasterDataToMesh.cpp
+++ b/Applications/Utils/MeshGeoTools/AssignRasterDataToMesh.cpp
@@ -13,10 +13,7 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Raster.h"
 #include "InfoLib/GitInfo.h"
@@ -74,9 +71,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     bool const create_cell_array(set_cells_arg.isSet());
     bool const create_node_array =
@@ -91,9 +86,6 @@ int main(int argc, char* argv[])
     if (mesh->getDimension() > 2)
     {
         ERR("Method can not be applied to 3D meshes.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -108,9 +100,6 @@ int main(int argc, char* argv[])
         if (!assigned)
         {
             ERR("Error assigning raster data to scalar node array");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
         INFO("Created node array {:s}", array_name_arg.getValue());
@@ -124,9 +113,6 @@ int main(int argc, char* argv[])
         if (!assigned)
         {
             ERR("Error assigning raster data to scalar cell array");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
         INFO("Created cell array {:s}", array_name_arg.getValue());
@@ -134,8 +120,5 @@ int main(int argc, char* argv[])
 
     MeshLib::IO::VtuInterface vtu(mesh.get());
     vtu.writeToFile(output_name);
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/IntegrateBoreholesIntoMesh.cpp b/Applications/Utils/MeshGeoTools/IntegrateBoreholesIntoMesh.cpp
index 6f0f5b701cd..9c88e921588 100644
--- a/Applications/Utils/MeshGeoTools/IntegrateBoreholesIntoMesh.cpp
+++ b/Applications/Utils/MeshGeoTools/IntegrateBoreholesIntoMesh.cpp
@@ -16,10 +16,7 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.h"
 #include "InfoLib/GitInfo.h"
@@ -122,9 +119,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::pair<int, int> mat_limits(0, std::numeric_limits<int>::max());
     std::pair<double, double> elevation_limits(
@@ -134,9 +129,6 @@ int main(int argc, char* argv[])
     {
         ERR("If minimum MaterialID is set, maximum ID must be set, too (and "
             "vice versa).");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     if (min_id_arg.isSet() && max_id_arg.isSet())
@@ -151,18 +143,12 @@ int main(int argc, char* argv[])
     if (min_id_arg.isSet() && (mat_limits.first < 0 || mat_limits.second < 0))
     {
         ERR("Specified MaterialIDs must have non-negative values.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     if (min_elevation_arg.isSet() != max_elevation_arg.isSet())
     {
         ERR("If minimum elevation is set, maximum elevation must be set, too "
             "(and vice versa).");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     if (min_elevation_arg.isSet() && max_elevation_arg.isSet())
@@ -184,9 +170,6 @@ int main(int argc, char* argv[])
     if (!xml_io.readFile(geo_name))
     {
         ERR("Failed to read geometry file `{:s}'.", geo_name);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     std::vector<GeoLib::Point*> const& points =
@@ -197,17 +180,11 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         ERR("Failed to read input mesh file `{:s}'.", mesh_name);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     if (mesh->getDimension() != 3)
     {
         ERR("Method can only be applied to 3D meshes.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -216,9 +193,6 @@ int main(int argc, char* argv[])
     if (mat_ids == nullptr)
     {
         ERR("Mesh is required to have MaterialIDs");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -256,8 +230,5 @@ int main(int argc, char* argv[])
                                true /* compute_element_neighbors */, props);
     MeshLib::IO::VtuInterface vtu(&result);
     vtu.writeToFile(output_name);
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/Raster2Mesh.cpp b/Applications/Utils/MeshGeoTools/Raster2Mesh.cpp
index c4905205da3..423ecc4d961 100644
--- a/Applications/Utils/MeshGeoTools/Raster2Mesh.cpp
+++ b/Applications/Utils/MeshGeoTools/Raster2Mesh.cpp
@@ -13,10 +13,7 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Raster.h"
 #include "InfoLib/GitInfo.h"
@@ -72,9 +69,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::string const input_name = input_arg.getValue().c_str();
     std::string const output_name = output_arg.getValue().c_str();
@@ -107,16 +102,10 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         ERR("Conversion failed.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
     MeshLib::IO::VtuInterface vtu(mesh.get());
     vtu.writeToFile(output_name);
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/VerticalSliceFromLayers.cpp b/Applications/Utils/MeshGeoTools/VerticalSliceFromLayers.cpp
index 671cdaeeae9..f9193a588cd 100644
--- a/Applications/Utils/MeshGeoTools/VerticalSliceFromLayers.cpp
+++ b/Applications/Utils/MeshGeoTools/VerticalSliceFromLayers.cpp
@@ -16,16 +16,13 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <QCoreApplication>
 
 #include "Applications/FileIO/Gmsh/GMSHInterface.h"
 #include "Applications/FileIO/Gmsh/GmshReader.h"
 #include "BaseLib/FileTools.h"
 #include "BaseLib/IO/readStringListFromFile.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/AABB.h"
 #include "GeoLib/AnalyticalGeometry.h"
 #include "GeoLib/GEOObjects.h"
@@ -418,9 +415,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::string const input_name = input_arg.getValue();
     std::string const output_name = output_arg.getValue();
@@ -439,9 +434,6 @@ int main(int argc, char* argv[])
     if (layer_names.size() < 2)
     {
         ERR("At least two layers are required to extract a slice.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -453,9 +445,6 @@ int main(int argc, char* argv[])
     {
         ERR("Less than two geometries could be created from layers. Aborting "
             "extraction...");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -475,9 +464,6 @@ int main(int argc, char* argv[])
     if (mesh == nullptr)
     {
         ERR("Error generating mesh... (GMSH was unable to output mesh)");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     rotateMesh(*mesh, rot_mat, z_shift);
@@ -485,9 +471,6 @@ int main(int argc, char* argv[])
     if (new_mesh == nullptr)
     {
         ERR("Error generating mesh... (GMSH created line mesh)");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -506,8 +489,5 @@ int main(int argc, char* argv[])
     }
     MeshLib::IO::VtuInterface vtu(revised_mesh.get());
     vtu.writeToFile(output_name + ".vtu");
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/computeSurfaceNodeIDsInPolygonalRegion.cpp b/Applications/Utils/MeshGeoTools/computeSurfaceNodeIDsInPolygonalRegion.cpp
index 5329c0b9ad9..4ca7478f6d4 100644
--- a/Applications/Utils/MeshGeoTools/computeSurfaceNodeIDsInPolygonalRegion.cpp
+++ b/Applications/Utils/MeshGeoTools/computeSurfaceNodeIDsInPolygonalRegion.cpp
@@ -12,10 +12,6 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <fstream>
 #include <memory>
@@ -25,6 +21,7 @@
 #include "Applications/FileIO/readGeometryFromFile.h"
 #include "BaseLib/Error.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/Polygon.h"
 #include "InfoLib/GitInfo.h"
@@ -101,9 +98,7 @@ int main(int argc, char* argv[])
     cmd.add(gmsh_path_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh const> mesh(
         MeshLib::IO::readMeshFromFile(mesh_in.getValue()));
@@ -194,8 +189,5 @@ int main(int argc, char* argv[])
     std::for_each(all_sfc_nodes.begin(), all_sfc_nodes.end(),
                   std::default_delete<MeshLib::Node>());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/constructMeshesFromGeometry.cpp b/Applications/Utils/MeshGeoTools/constructMeshesFromGeometry.cpp
index d57974e0476..9d99fc3e19d 100644
--- a/Applications/Utils/MeshGeoTools/constructMeshesFromGeometry.cpp
+++ b/Applications/Utils/MeshGeoTools/constructMeshesFromGeometry.cpp
@@ -10,6 +10,7 @@
 
 #include <tclap/CmdLine.h>
 
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.h"
 #include "InfoLib/GitInfo.h"
@@ -19,9 +20,6 @@
 #include "MeshLib/IO/writeMeshToFile.h"
 #include "MeshLib/Mesh.h"
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
 std::unique_ptr<GeoLib::GEOObjects> readGeometry(std::string const& filename)
 {
     auto geo_objects = std::make_unique<GeoLib::GEOObjects>();
@@ -80,9 +78,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
     std::unique_ptr<MeshLib::Mesh> mesh{
         MeshLib::IO::readMeshFromFile(mesh_arg.getValue())};
 
@@ -101,9 +97,6 @@ int main(int argc, char* argv[])
         if (!m_ptr)
         {
             ERR("Could not create a mesh for each given geometry.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
         if (m_ptr->getNodes().empty())
@@ -117,8 +110,5 @@ int main(int argc, char* argv[])
         MeshLib::IO::writeMeshToFile(*m_ptr, m_ptr->getName() + ".vtu");
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/createIntermediateRasters.cpp b/Applications/Utils/MeshGeoTools/createIntermediateRasters.cpp
index 2a98a25c57d..75a7572a964 100644
--- a/Applications/Utils/MeshGeoTools/createIntermediateRasters.cpp
+++ b/Applications/Utils/MeshGeoTools/createIntermediateRasters.cpp
@@ -9,14 +9,11 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <memory>
 #include <string>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Raster.h"
 #include "InfoLib/GitInfo.h"
@@ -50,9 +47,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<GeoLib::Raster> dem1(
         FileIO::AsciiRasterInterface::readRaster(input1_arg.getValue()));
@@ -61,9 +56,6 @@ int main(int argc, char* argv[])
 
     if (dem1 == nullptr || dem2 == nullptr)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 1;
     }
 
@@ -99,9 +91,6 @@ int main(int argc, char* argv[])
 
     if (errors_found)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 2;
     }
 
@@ -120,9 +109,6 @@ int main(int argc, char* argv[])
         if (it2 == dem2->end())
         {
             ERR("Error: File 2 is shorter than File 1.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return 3;
         }
         if (*it1 == h1.no_data || *it2 == h2.no_data)
@@ -147,9 +133,6 @@ int main(int argc, char* argv[])
     if (it2 != dem2->end())
     {
         ERR("Error: File 1 is shorter than File 2.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return 3;
     }
 
@@ -164,8 +147,5 @@ int main(int argc, char* argv[])
             r, basename + std::to_string(i) + ext);
         INFO("Layer {:d} written.", i + 1);
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/geometryToGmshGeo.cpp b/Applications/Utils/MeshGeoTools/geometryToGmshGeo.cpp
index 87777c243a7..87d735950a4 100644
--- a/Applications/Utils/MeshGeoTools/geometryToGmshGeo.cpp
+++ b/Applications/Utils/MeshGeoTools/geometryToGmshGeo.cpp
@@ -12,11 +12,8 @@
 // ThirdParty
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "Applications/FileIO/Gmsh/GMSHInterface.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.h"
 #include "InfoLib/GitInfo.h"
@@ -70,9 +67,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     GeoLib::GEOObjects geo_objects;
     for (auto const& geometry_name : geo_input_arg.getValue())
@@ -82,9 +77,6 @@ int main(int argc, char* argv[])
         {
             if (!xml.readFile(geometry_name))
             {
-#ifdef USE_PETSC
-                MPI_Finalize();
-#endif
                 return EXIT_FAILURE;
             }
         }
@@ -92,9 +84,6 @@ int main(int argc, char* argv[])
         {
             ERR("Failed to read file '{:s}'.", geometry_name);
             ERR("{:s}", err.what());
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
         INFO("Successfully read file '{:s}'.", geometry_name);
@@ -155,13 +144,7 @@ int main(int argc, char* argv[])
                 "for better analysis of the problem.");
         }
         ERR("An error has occurred - programme will be terminated.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/MeshGeoTools/identifySubdomains.cpp b/Applications/Utils/MeshGeoTools/identifySubdomains.cpp
index 46e44c801d5..fcfba24983f 100644
--- a/Applications/Utils/MeshGeoTools/identifySubdomains.cpp
+++ b/Applications/Utils/MeshGeoTools/identifySubdomains.cpp
@@ -10,10 +10,7 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
+#include "BaseLib/MPI.h"
 #include "BaseLib/RunTime.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshGeoToolsLib/IdentifySubdomainMesh.h"
@@ -98,9 +95,7 @@ int main(int argc, char* argv[])
     cmd.add(subdomain_meshes_filenames_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     //
     // The bulk mesh.
@@ -165,9 +160,6 @@ int main(int argc, char* argv[])
     }
     INFO("writing time: {:g} s", writing_time.elapsed());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     INFO("Entire run time: {:g} s", run_time.elapsed());
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp b/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
index c29a8bc4bbf..9bad7b3970a 100644
--- a/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
+++ b/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
@@ -11,10 +11,6 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <fstream>
 #include <memory>
 #include <numeric>
@@ -23,6 +19,7 @@
 
 #include "BaseLib/Error.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/Mesh.h"
@@ -90,9 +87,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh> surface_mesh(
         MeshLib::IO::readMeshFromFile(mesh_in.getValue()));
@@ -112,9 +107,6 @@ int main(int argc, char* argv[])
         if (!orig_node_ids)
         {
             ERR("Fatal error: could not create property.");
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
         orig_node_ids->resize(surface_mesh->getNumberOfNodes());
@@ -149,8 +141,5 @@ int main(int argc, char* argv[])
     writeToFile(id_and_area_fname, csv_fname, ids_and_areas,
                 surface_mesh->getNodes());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/BinaryToPVTU.cpp b/Applications/Utils/ModelPreparation/PartitionMesh/BinaryToPVTU.cpp
index fd7b3baca9c..81ce322f9ec 100644
--- a/Applications/Utils/ModelPreparation/PartitionMesh/BinaryToPVTU.cpp
+++ b/Applications/Utils/ModelPreparation/PartitionMesh/BinaryToPVTU.cpp
@@ -10,7 +10,6 @@
 
 */
 
-#include <mpi.h>
 #include <spdlog/spdlog.h>
 #include <tclap/CmdLine.h>
 #include <vtkMPIController.h>
@@ -18,6 +17,7 @@
 
 #include "BaseLib/CPUTime.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/RunTime.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/VtkIO/VtuInterface.h"
@@ -72,9 +72,7 @@ int main(int argc, char* argv[])
             OGS_FATAL("spdlog logger error occurred.");
         });
 
-    // init MPI
-    MPI_Init(&argc, &argv);
-
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
     // start the timer
     BaseLib::RunTime run_timer;
     run_timer.start();
@@ -111,8 +109,5 @@ int main(int argc, char* argv[])
 
     INFO("Total runtime: {:g} s.", run_timer.elapsed());
     INFO("Total CPU time: {:g} s.", CPU_timer.elapsed());
-
-    MPI_Finalize();
-
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/PartitionMesh.cpp b/Applications/Utils/ModelPreparation/PartitionMesh/PartitionMesh.cpp
index daa2aa43cd3..3e531631385 100644
--- a/Applications/Utils/ModelPreparation/PartitionMesh/PartitionMesh.cpp
+++ b/Applications/Utils/ModelPreparation/PartitionMesh/PartitionMesh.cpp
@@ -15,12 +15,9 @@
 #include <spdlog/spdlog.h>
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "BaseLib/CPUTime.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/RunTime.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -102,9 +99,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     BaseLib::setConsoleLogLevel(log_level_arg.getValue());
     spdlog::set_pattern("%^%l:%$ %v");
@@ -144,9 +139,6 @@ int main(int argc, char* argv[])
         INFO("Total runtime: {:g} s.", run_timer.elapsed());
         INFO("Total CPU time: {:g} s.", CPU_timer.elapsed());
 
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_SUCCESS;
     }
 
@@ -192,9 +184,6 @@ int main(int argc, char* argv[])
         {
             INFO("Failed in system calling.");
             INFO("Return value of system call {:d} ", status);
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
@@ -244,8 +233,5 @@ int main(int argc, char* argv[])
     INFO("Total runtime: {:g} s.", run_timer.elapsed());
     INFO("Total CPU time: {:g} s.", CPU_timer.elapsed());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/ModelPreparation/convertVtkDataArrayToVtkDataArray.cpp b/Applications/Utils/ModelPreparation/convertVtkDataArrayToVtkDataArray.cpp
index dbb156149c0..0fd23a6fe3c 100644
--- a/Applications/Utils/ModelPreparation/convertVtkDataArrayToVtkDataArray.cpp
+++ b/Applications/Utils/ModelPreparation/convertVtkDataArrayToVtkDataArray.cpp
@@ -11,15 +11,12 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <cmath>
 #include <memory>
 #include <numeric>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -105,18 +102,13 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh> mesh(
         MeshLib::IO::readMeshFromFile(mesh_arg.getValue()));
 
     if (!mesh)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 
@@ -163,16 +155,10 @@ int main(int argc, char* argv[])
     if (!success)
     {
         ERR("{:s}", err_msg);
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 
     MeshLib::IO::writeMeshToFile(*mesh, out_mesh_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/ModelPreparation/createNeumannBc.cpp b/Applications/Utils/ModelPreparation/createNeumannBc.cpp
index 7f108478b1f..b69f69c4861 100644
--- a/Applications/Utils/ModelPreparation/createNeumannBc.cpp
+++ b/Applications/Utils/ModelPreparation/createNeumannBc.cpp
@@ -10,12 +10,9 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <fstream>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -130,9 +127,7 @@ int main(int argc, char* argv[])
     cmd.add(result_file);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // read surface mesh
     std::unique_ptr<MeshLib::Mesh> surface_mesh(
@@ -155,9 +150,6 @@ int main(int argc, char* argv[])
     }();
     if (!node_id_pv)
     {
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
 
@@ -192,8 +184,5 @@ int main(int argc, char* argv[])
         result_out << p.first << " " << p.second << "\n";
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/ModelPreparation/scaleProperty.cpp b/Applications/Utils/ModelPreparation/scaleProperty.cpp
index 03eb59846b7..562ee1d9212 100644
--- a/Applications/Utils/ModelPreparation/scaleProperty.cpp
+++ b/Applications/Utils/ModelPreparation/scaleProperty.cpp
@@ -11,15 +11,12 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <cmath>
 #include <memory>
 #include <numeric>
 
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -72,9 +69,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::unique_ptr<MeshLib::Mesh> mesh(
         MeshLib::IO::readMeshFromFile(mesh_arg.getValue()));
@@ -97,8 +92,5 @@ int main(int argc, char* argv[])
 
     MeshLib::IO::writeMeshToFile(*mesh, out_mesh_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/PostProcessing/Raster2PointCloud.cpp b/Applications/Utils/PostProcessing/Raster2PointCloud.cpp
index 2b22e4fde07..44fa7de536f 100644
--- a/Applications/Utils/PostProcessing/Raster2PointCloud.cpp
+++ b/Applications/Utils/PostProcessing/Raster2PointCloud.cpp
@@ -13,9 +13,6 @@
 
 // ThirdParty
 #include <tclap/CmdLine.h>
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
 #include <vtkPolyDataAlgorithm.h>
 #include <vtkSmartPointer.h>
 #include <vtkXMLPolyDataWriter.h>
@@ -23,6 +20,7 @@
 #include "Applications/DataExplorer/VtkVis/VtkGeoImageSource.h"
 #include "Applications/DataExplorer/VtkVis/VtkImageDataToPointCloudFilter.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "InfoLib/GitInfo.h"
 
@@ -80,9 +78,7 @@ int main(int argc, char* argv[])
     cmd.add(input_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     std::string const input_name = input_arg.getValue().c_str();
     std::string const output_name = output_arg.getValue().c_str();
@@ -161,8 +157,5 @@ int main(int argc, char* argv[])
         }
     }
     std::cout << "done." << std::endl;
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/PostProcessing/postLIE.cpp b/Applications/Utils/PostProcessing/postLIE.cpp
index 86199ac4055..dac283371f5 100644
--- a/Applications/Utils/PostProcessing/postLIE.cpp
+++ b/Applications/Utils/PostProcessing/postLIE.cpp
@@ -9,10 +9,6 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/xml_parser.hpp>
 #include <map>
@@ -20,6 +16,7 @@
 #include <vector>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "InfoLib/GitInfo.h"
 #include "MeshLib/IO/readMeshFromFile.h"
 #include "MeshLib/IO/writeMeshToFile.h"
@@ -151,9 +148,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     auto const in_file_ext = BaseLib::getFileExtension(arg_in_file.getValue());
     if (in_file_ext == ".pvd")
@@ -170,8 +165,5 @@ int main(int argc, char* argv[])
         OGS_FATAL("The given file type ({:s}) is not supported.", in_file_ext);
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/SWMMConverter/SWMMConverter.cpp b/Applications/Utils/SWMMConverter/SWMMConverter.cpp
index 7db44c2b4af..be95e7c6128 100644
--- a/Applications/Utils/SWMMConverter/SWMMConverter.cpp
+++ b/Applications/Utils/SWMMConverter/SWMMConverter.cpp
@@ -9,12 +9,9 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include "Applications/FileIO/SWMM/SWMMInterface.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/StringTools.h"
 #include "GeoLib/GEOObjects.h"
 #include "GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.h"
@@ -199,18 +196,13 @@ int main(int argc, char* argv[])
     cmd.add(add_system_arg);
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     if (!(geo_output_arg.isSet() || mesh_output_arg.isSet() ||
           csv_output_arg.isSet()))
     {
         ERR("No output format given. Please specify OGS geometry or mesh "
             "output file.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 
@@ -219,9 +211,6 @@ int main(int argc, char* argv[])
     {
         ERR("Please specify csv output file for exporting subcatchment or "
             "system parameters.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return -1;
     }
 
@@ -240,8 +229,5 @@ int main(int argc, char* argv[])
                        add_subcatchments_arg.getValue(),
                        add_system_arg.getValue());
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return 0;
 }
diff --git a/Applications/Utils/SimpleMeshCreation/createMeshElemPropertiesFromASCRaster.cpp b/Applications/Utils/SimpleMeshCreation/createMeshElemPropertiesFromASCRaster.cpp
index 9039a44a134..00b7dfedf5a 100644
--- a/Applications/Utils/SimpleMeshCreation/createMeshElemPropertiesFromASCRaster.cpp
+++ b/Applications/Utils/SimpleMeshCreation/createMeshElemPropertiesFromASCRaster.cpp
@@ -12,16 +12,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <cmath>
 #include <memory>
 #include <numeric>
 
 #include "BaseLib/FileTools.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/quicksort.h"
 #include "GeoLib/IO/AsciiRasterInterface.h"
 #include "GeoLib/Raster.h"
@@ -94,9 +91,7 @@ int main(int argc, char* argv[])
 
     cmd.parse(argc, argv);
 
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
 
     // read mesh
     std::unique_ptr<MeshLib::Mesh> dest_mesh(
@@ -138,8 +133,5 @@ int main(int argc, char* argv[])
         MeshLib::IO::writeMeshToFile(*dest_mesh, out_mesh_arg.getValue());
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
diff --git a/Applications/Utils/SimpleMeshCreation/generateStructuredMesh.cpp b/Applications/Utils/SimpleMeshCreation/generateStructuredMesh.cpp
index 7e3062698a3..0392559aae0 100644
--- a/Applications/Utils/SimpleMeshCreation/generateStructuredMesh.cpp
+++ b/Applications/Utils/SimpleMeshCreation/generateStructuredMesh.cpp
@@ -9,16 +9,13 @@
 
 #include <tclap/CmdLine.h>
 
-#ifdef USE_PETSC
-#include <mpi.h>
-#endif
-
 #include <algorithm>
 #include <memory>
 #include <string>
 #include <vector>
 
 #include "BaseLib/Error.h"
+#include "BaseLib/MPI.h"
 #include "BaseLib/Subdivision.h"
 #include "BaseLib/TCLAPCustomOutput.h"
 #include "InfoLib/GitInfo.h"
@@ -161,9 +158,7 @@ int main(int argc, char* argv[])
 
     // parse arguments
     cmd.parse(argc, argv);
-#ifdef USE_PETSC
-    MPI_Init(&argc, &argv);
-#endif
+    BaseLib::MPI::Setup mpi_setup(argc, argv);
     const std::string eleTypeName(eleTypeArg.getValue());
     const MeshLib::MeshElemType eleType =
         MeshLib::String2MeshElemType(eleTypeName);
@@ -194,9 +189,6 @@ int main(int argc, char* argv[])
     if (!isLengthSet)
     {
         ERR("Missing input: Length information is not provided at all.");
-#ifdef USE_PETSC
-        MPI_Finalize();
-#endif
         return EXIT_FAILURE;
     }
     for (unsigned i = 0; i < 3; i++)
@@ -206,9 +198,6 @@ int main(int argc, char* argv[])
             ERR("Missing input: Length for dimension [{:d}] is required but "
                 "missing.",
                 i);
-#ifdef USE_PETSC
-            MPI_Finalize();
-#endif
             return EXIT_FAILURE;
         }
     }
@@ -304,8 +293,5 @@ int main(int argc, char* argv[])
             *(mesh.get()), std::filesystem::path(mesh_out.getValue()));
     }
 
-#ifdef USE_PETSC
-    MPI_Finalize();
-#endif
     return EXIT_SUCCESS;
 }
-- 
GitLab