From 16ce64ad69ef39f0b3eee8be0723f5ecdc3e2171 Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <dmitri.naumov@ufz.de>
Date: Tue, 30 Jan 2024 17:09:41 +0100
Subject: [PATCH] [MeL] Add findMeshByName() used often

Remove unused version of findElementOrError with iterators
and error string.
---
 Applications/ApplicationsLib/ProjectData.cpp   | 14 +++-----------
 Applications/ApplicationsLib/ProjectData.h     |  2 +-
 Applications/ApplicationsLib/Simulation.cpp    |  2 +-
 Applications/ApplicationsLib/Simulation.h      |  2 +-
 .../Python/ogs.simulator/ogs_python_module.cpp |  2 +-
 BaseLib/Algorithm.h                            | 13 -------------
 ChemistryLib/CreateChemicalSolverInterface.cpp | 18 ++----------------
 MeshLib/Mesh.cpp                               | 13 +++++++++++++
 MeshLib/Mesh.h                                 |  4 ++++
 ParameterLib/Parameter.cpp                     | 10 ++--------
 ProcessLib/Output/CreateOutputConfig.cpp       |  9 +--------
 ProcessLib/Output/Output.cpp                   |  7 ++-----
 ProcessLib/ProcessVariable.cpp                 |  9 +--------
 ProcessLib/SurfaceFlux/SurfaceFluxData.cpp     |  6 +-----
 14 files changed, 33 insertions(+), 78 deletions(-)

diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp
index 575775e0d0d..6b2b5896127 100644
--- a/Applications/ApplicationsLib/ProjectData.cpp
+++ b/Applications/ApplicationsLib/ProjectData.cpp
@@ -447,10 +447,7 @@ void ProjectData::parseProcessVariables(
             var_config.getConfigParameter<std::string>("mesh",
                                                        _mesh_vec[0]->getName());
 
-        auto& mesh = *BaseLib::findElementOrError(
-            begin(_mesh_vec), end(_mesh_vec),
-            [&mesh_name](auto const& m) { return m->getName() == mesh_name; },
-            "Expected to find a mesh named " + mesh_name + ".");
+        auto& mesh = MeshLib::findMeshByName(_mesh_vec, mesh_name);
 
         auto pv = ProcessLib::ProcessVariable{var_config, mesh, _mesh_vec,
                                               _parameters, _curves};
@@ -1362,12 +1359,7 @@ void ProjectData::parseCurves(std::optional<BaseLib::ConfigTree> const& config)
     }
 }
 
-MeshLib::Mesh* ProjectData::getMesh(std::string const& mesh_name) const
+MeshLib::Mesh& ProjectData::getMesh(std::string const& mesh_name) const
 {
-    return BaseLib::findElementOrError(
-               begin(_mesh_vec), end(_mesh_vec),
-               [&mesh_name](auto const& m)
-               { return m->getName() == mesh_name; },
-               "Expected to find a mesh named " + mesh_name + ".")
-        .get();
+    return MeshLib::findMeshByName(_mesh_vec, mesh_name);
 }
diff --git a/Applications/ApplicationsLib/ProjectData.h b/Applications/ApplicationsLib/ProjectData.h
index 6cbd7d45088..c230423b159 100644
--- a/Applications/ApplicationsLib/ProjectData.h
+++ b/Applications/ApplicationsLib/ProjectData.h
@@ -94,7 +94,7 @@ public:
 
     ProcessLib::TimeLoop& getTimeLoop() { return *_time_loop; }
 
-    MeshLib::Mesh* getMesh(std::string const& mesh_name) const;
+    MeshLib::Mesh& getMesh(std::string const& mesh_name) const;
 
     std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const&
     getMedia() const
diff --git a/Applications/ApplicationsLib/Simulation.cpp b/Applications/ApplicationsLib/Simulation.cpp
index f641e145161..1ee83988744 100644
--- a/Applications/ApplicationsLib/Simulation.cpp
+++ b/Applications/ApplicationsLib/Simulation.cpp
@@ -139,7 +139,7 @@ bool Simulation::executeTimeStep()
     return false;
 }
 
-MeshLib::Mesh* Simulation::getMesh(std::string const& name)
+MeshLib::Mesh& Simulation::getMesh(std::string const& name)
 {
     return project_data->getMesh(name);
 }
diff --git a/Applications/ApplicationsLib/Simulation.h b/Applications/ApplicationsLib/Simulation.h
index 4eccbb09ffa..7aff506877e 100644
--- a/Applications/ApplicationsLib/Simulation.h
+++ b/Applications/ApplicationsLib/Simulation.h
@@ -43,7 +43,7 @@ public:
     OGS_EXPORT_SYMBOL bool executeTimeStep();
     OGS_EXPORT_SYMBOL bool executeSimulation();
     OGS_EXPORT_SYMBOL void outputLastTimeStep() const;
-    OGS_EXPORT_SYMBOL MeshLib::Mesh* getMesh(std::string const& name);
+    OGS_EXPORT_SYMBOL MeshLib::Mesh& getMesh(std::string const& name);
 
     OGS_EXPORT_SYMBOL std::optional<ApplicationsLib::TestDefinition>
     getTestDefinition() const;
diff --git a/Applications/Python/ogs.simulator/ogs_python_module.cpp b/Applications/Python/ogs.simulator/ogs_python_module.cpp
index 13fb2eacde8..35d48baa74c 100644
--- a/Applications/Python/ogs.simulator/ogs_python_module.cpp
+++ b/Applications/Python/ogs.simulator/ogs_python_module.cpp
@@ -168,7 +168,7 @@ double endTime()
 
 OGSMesh getMesh(std::string const& name)
 {
-    return OGSMesh(*simulation->getMesh(name));
+    return OGSMesh(simulation->getMesh(name));
 }
 
 void finalize()
diff --git a/BaseLib/Algorithm.h b/BaseLib/Algorithm.h
index 07c86faa2d5..cc0c0d495b6 100644
--- a/BaseLib/Algorithm.h
+++ b/BaseLib/Algorithm.h
@@ -90,19 +90,6 @@ ranges::range_reference_t<Range> findElementOrError(
     return *it;
 }
 
-template <typename InputIt, typename Predicate>
-typename std::iterator_traits<InputIt>::reference findElementOrError(
-    InputIt begin, InputIt end, Predicate predicate,
-    std::string const& error = "")
-{
-    auto it = std::find_if(begin, end, predicate);
-    if (it == end)
-    {
-        OGS_FATAL("Element not found in the input range; {:s}", error);
-    }
-    return *it;
-}
-
 //! Inserts the given \c key with the given \c value into the \c map if an entry
 //! with the
 //! given \c key does not yet exist; otherwise an \c error_message is printed
diff --git a/ChemistryLib/CreateChemicalSolverInterface.cpp b/ChemistryLib/CreateChemicalSolverInterface.cpp
index 3d92a0025f9..e57f74cfe78 100644
--- a/ChemistryLib/CreateChemicalSolverInterface.cpp
+++ b/ChemistryLib/CreateChemicalSolverInterface.cpp
@@ -76,14 +76,7 @@ createChemicalSolverInterface<ChemicalSolver::Phreeqc>(
         config.getConfigParameter<std::string>("mesh");
 
     // Find and extract mesh from the list of meshes.
-    auto const& mesh = *BaseLib::findElementOrError(
-        std::begin(meshes), std::end(meshes),
-        [&mesh_name](auto const& mesh)
-        {
-            assert(mesh != nullptr);
-            return mesh->getName() == mesh_name;
-        },
-        "Required mesh with name '" + mesh_name + "' not found.");
+    auto const& mesh = MeshLib::findMeshByName(meshes, mesh_name);
 
     assert(mesh.getID() != 0);
     DBUG("Found mesh '{:s}' with id {:d}.", mesh.getName(), mesh.getID());
@@ -207,14 +200,7 @@ createChemicalSolverInterface<ChemicalSolver::SelfContained>(
         config.getConfigParameter<std::string>("mesh");
 
     // Find and extract mesh from the list of meshes.
-    auto const& mesh = *BaseLib::findElementOrError(
-        std::begin(meshes), std::end(meshes),
-        [&mesh_name](auto const& mesh)
-        {
-            assert(mesh != nullptr);
-            return mesh->getName() == mesh_name;
-        },
-        "Required mesh with name '" + mesh_name + "' not found.");
+    auto const& mesh = MeshLib::findMeshByName(meshes, mesh_name);
 
     assert(mesh.getID() != 0);
     DBUG("Found mesh '{:s}' with id {:d}.", mesh.getName(), mesh.getID());
diff --git a/MeshLib/Mesh.cpp b/MeshLib/Mesh.cpp
index b8424090221..1cf62c20b42 100644
--- a/MeshLib/Mesh.cpp
+++ b/MeshLib/Mesh.cpp
@@ -360,4 +360,17 @@ bool isBaseNode(Node const& node,
     return local_index < n_base_nodes;
 }
 
+Mesh& findMeshByName(std::vector<std::unique_ptr<Mesh>> const& meshes,
+                     std::string_view const name)
+{
+    return *BaseLib::findElementOrError(
+        meshes,
+        [&name](auto const& mesh)
+        {
+            assert(mesh != nullptr);
+            return mesh->getName() == name;
+        },
+        [&]() { OGS_FATAL("Required mesh named {:s} not found.", name); });
+}
+
 }  // namespace MeshLib
diff --git a/MeshLib/Mesh.h b/MeshLib/Mesh.h
index d05a130ec24..82e5d3b0faa 100644
--- a/MeshLib/Mesh.h
+++ b/MeshLib/Mesh.h
@@ -20,6 +20,7 @@
 #include <string>
 #include <vector>
 
+#include "BaseLib/Algorithm.h"
 #include "BaseLib/Error.h"
 #include "MathLib/Point3d.h"
 #include "MeshEnums.h"
@@ -214,6 +215,9 @@ bool idsComparator(T const a, T const b)
     }
 }
 
+Mesh& findMeshByName(std::vector<std::unique_ptr<Mesh>> const& meshes,
+                     std::string_view const name);
+
 /// MeshLib specific, lazy, non-owning, non-mutating, composable range views.
 namespace views
 {
diff --git a/ParameterLib/Parameter.cpp b/ParameterLib/Parameter.cpp
index c293926f84d..4a15a2885fe 100644
--- a/ParameterLib/Parameter.cpp
+++ b/ParameterLib/Parameter.cpp
@@ -43,10 +43,7 @@ std::unique_ptr<ParameterBase> createParameter(
         //! \ogs_file_param{prj__parameters__parameter__mesh}
         config.getConfigParameter<std::string>("mesh", meshes[0]->getName());
 
-    auto const& mesh = *BaseLib::findElementOrError(
-        begin(meshes), end(meshes),
-        [&mesh_name](auto const& m) { return m->getName() == mesh_name; },
-        "Expected to find a mesh named " + mesh_name + ".");
+    auto const& mesh = MeshLib::findMeshByName(meshes, mesh_name);
 
     // Create parameter based on the provided type.
     if (type == "Constant")
@@ -81,10 +78,7 @@ std::unique_ptr<ParameterBase> createParameter(
     }
     if (type == "RandomFieldMeshElement")
     {
-        auto& mesh_var = *BaseLib::findElementOrError(
-            begin(meshes), end(meshes),
-            [&mesh_name](auto const& m) { return m->getName() == mesh_name; },
-            "Expected to find a mesh named " + mesh_name + ".");
+        auto& mesh_var = MeshLib::findMeshByName(meshes, mesh_name);
         INFO("RandomFieldMeshElement: {:s}", name);
         return createRandomFieldMeshElementParameter(name, config, mesh_var);
     }
diff --git a/ProcessLib/Output/CreateOutputConfig.cpp b/ProcessLib/Output/CreateOutputConfig.cpp
index 70563f6b128..6465bd9f134 100644
--- a/ProcessLib/Output/CreateOutputConfig.cpp
+++ b/ProcessLib/Output/CreateOutputConfig.cpp
@@ -37,14 +37,7 @@ std::string parseOutputMeshConfig(
     std::vector<std::unique_ptr<MeshLib::Mesh>>& meshes)
 {
     auto const mesh_name = output_mesh_config.getValue<std::string>();
-    auto const& mesh = *BaseLib::findElementOrError(
-        begin(meshes), end(meshes),
-        [&mesh_name](auto const& mesh)
-        {
-            assert(mesh != nullptr);
-            return mesh->getName() == mesh_name;
-        },
-        "Required mesh with name '" + mesh_name + "' not found.");
+    auto const& mesh = MeshLib::findMeshByName(meshes, mesh_name);
 
     auto material_id_string =
         //! \ogs_file_attr{prj__time_loop__output__meshes__mesh__material_ids}
diff --git a/ProcessLib/Output/Output.cpp b/ProcessLib/Output/Output.cpp
index e33fd13bbf1..799af5ef7c8 100644
--- a/ProcessLib/Output/Output.cpp
+++ b/ProcessLib/Output/Output.cpp
@@ -22,6 +22,7 @@
 #include "BaseLib/FileTools.h"
 #include "BaseLib/Logging.h"
 #include "BaseLib/RunTime.h"
+#include "MeshLib/Mesh.h"
 #include "MeshLib/Utils/getOrCreateMeshProperty.h"
 #include "ProcessLib/Process.h"
 
@@ -215,11 +216,7 @@ MeshLib::Mesh const& Output::prepareSubmesh(
     const int process_id, double const t,
     std::vector<GlobalVector*> const& xs) const
 {
-    auto& submesh = *BaseLib::findElementOrError(
-        _meshes.get().begin(), _meshes.get().end(),
-        [&submesh_output_name](auto const& m)
-        { return m->getName() == submesh_output_name; },
-        "Need mesh '" + submesh_output_name + "' for the output.");
+    auto& submesh = MeshLib::findMeshByName(_meshes.get(), submesh_output_name);
 
     DBUG("Found {:d} nodes for output at mesh '{:s}'.",
          submesh.getNumberOfNodes(), submesh.getName());
diff --git a/ProcessLib/ProcessVariable.cpp b/ProcessLib/ProcessVariable.cpp
index 628ba737cc8..ffffaa19ccc 100644
--- a/ProcessLib/ProcessVariable.cpp
+++ b/ProcessLib/ProcessVariable.cpp
@@ -78,14 +78,7 @@ MeshLib::Mesh const& findMeshInConfig(
     //
     // Find and extract mesh from the list of meshes.
     //
-    auto const& mesh = *BaseLib::findElementOrError(
-        begin(meshes), end(meshes),
-        [&mesh_name](auto const& mesh)
-        {
-            assert(mesh != nullptr);
-            return mesh->getName() == mesh_name;
-        },
-        "Required mesh with name '" + mesh_name + "' not found.");
+    auto const& mesh = MeshLib::findMeshByName(meshes, mesh_name);
     DBUG("Found mesh '{:s}' with id {:d}.", mesh.getName(), mesh.getID());
 
     return mesh;
diff --git a/ProcessLib/SurfaceFlux/SurfaceFluxData.cpp b/ProcessLib/SurfaceFlux/SurfaceFluxData.cpp
index 9ff0691f8c1..84c041a8c21 100644
--- a/ProcessLib/SurfaceFlux/SurfaceFluxData.cpp
+++ b/ProcessLib/SurfaceFlux/SurfaceFluxData.cpp
@@ -52,11 +52,7 @@ SurfaceFluxData::createSurfaceFluxData(
         "'{:s}'\n",
         mesh_name, surfaceflux_pv_name);
 
-    auto& surfaceflux_mesh = *BaseLib::findElementOrError(
-        meshes.begin(), meshes.end(),
-        [&mesh_name](auto const& m) { return mesh_name == m->getName(); },
-        "Expected to find a mesh named " + mesh_name +
-            " for the surfaceflux calculation.");
+    auto& surfaceflux_mesh = MeshLib::findMeshByName(meshes, mesh_name);
 
     return std::make_unique<SurfaceFluxData>(surfaceflux_mesh,
                                              std::move(surfaceflux_pv_name));
-- 
GitLab