From 3ac0c14ef842fd9de49e0226bb3863eed2141bc2 Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <github@naumov.de>
Date: Wed, 31 Aug 2022 19:00:21 +0200
Subject: [PATCH] [MaL] Move linear solver options parser in own TU

---
 .../Eigen/LinearSolverOptionsParser.cpp       | 146 ++++++++++++++++++
 .../LinAlg/Eigen/LinearSolverOptionsParser.h  | 138 +----------------
 .../EigenLis/LinearSolverOptionsParser.cpp    |  42 +++++
 .../EigenLis/LinearSolverOptionsParser.h      |  27 +---
 .../PETSc/LinearSolverOptionsParser.cpp       |  52 +++++++
 .../LinAlg/PETSc/LinearSolverOptionsParser.h  |  41 +----
 6 files changed, 257 insertions(+), 189 deletions(-)
 create mode 100644 MathLib/LinAlg/Eigen/LinearSolverOptionsParser.cpp
 create mode 100644 MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.cpp
 create mode 100644 MathLib/LinAlg/PETSc/LinearSolverOptionsParser.cpp

diff --git a/MathLib/LinAlg/Eigen/LinearSolverOptionsParser.cpp b/MathLib/LinAlg/Eigen/LinearSolverOptionsParser.cpp
new file mode 100644
index 00000000000..56d37a10e69
--- /dev/null
+++ b/MathLib/LinAlg/Eigen/LinearSolverOptionsParser.cpp
@@ -0,0 +1,146 @@
+/**
+ * \file
+ * \copyright
+ * Copyright (c) 2012-2022, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "LinearSolverOptionsParser.h"
+
+#include "BaseLib/ConfigTree.h"
+#include "BaseLib/Error.h"
+#include "MathLib/LinAlg/LinearSolverOptions.h"
+
+namespace MathLib
+{
+std::tuple<std::string, EigenOption>
+LinearSolverOptionsParser<EigenLinearSolver>::parseNameAndOptions(
+    std::string const& prefix,
+    BaseLib::ConfigTree const* const solver_config) const
+{
+    if (!solver_config)
+    {
+        return {prefix, EigenOption{}};
+    }
+
+    ignoreOtherLinearSolvers(*solver_config, "eigen");
+    //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen}
+    auto const config = solver_config->getConfigSubtreeOptional("eigen");
+    if (!config)
+    {
+        OGS_FATAL(
+            "OGS was compiled with Eigen but the config section in the "
+            "project file seems to be invalid");
+    }
+
+    EigenOption options;
+
+    if (auto solver_type =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__solver_type}
+        config->getConfigParameterOptional<std::string>("solver_type"))
+    {
+        options.solver_type = MathLib::EigenOption::getSolverType(*solver_type);
+    }
+    if (auto precon_type =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__precon_type}
+        config->getConfigParameterOptional<std::string>("precon_type"))
+    {
+        options.precon_type = MathLib::EigenOption::getPreconType(*precon_type);
+    }
+    if (auto error_tolerance =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__error_tolerance}
+        config->getConfigParameterOptional<double>("error_tolerance"))
+    {
+        options.error_tolerance = *error_tolerance;
+    }
+    if (auto max_iteration_step =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__max_iteration_step}
+        config->getConfigParameterOptional<int>("max_iteration_step"))
+    {
+        options.max_iterations = *max_iteration_step;
+    }
+    if (auto scaling =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__scaling}
+        config->getConfigParameterOptional<bool>("scaling"))
+    {
+#ifdef USE_EIGEN_UNSUPPORTED
+        options.scaling = *scaling;
+#else
+        OGS_FATAL(
+            "The code is not compiled with the Eigen unsupported modules. "
+            "scaling is not available.");
+#endif
+    }
+    if (auto restart =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__restart}
+        config->getConfigParameterOptional<int>("restart"))
+    {
+#ifdef USE_EIGEN_UNSUPPORTED
+        options.restart = *restart;
+#else
+        OGS_FATAL(
+            "The code is not compiled with the Eigen unsupported modules. "
+            "GMRES/GMRES option restart is not available.");
+#endif
+    }
+    if (auto l =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__l}
+        config->getConfigParameterOptional<int>("l"))
+    {
+#ifdef USE_EIGEN_UNSUPPORTED
+        options.l = *l;
+#else
+        OGS_FATAL(
+            "The code is not compiled with the Eigen unsupported modules.");
+#endif
+    }
+    if (auto s =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__s}
+        config->getConfigParameterOptional<int>("s"))
+    {
+#ifdef USE_EIGEN_UNSUPPORTED
+        options.s = *s;
+#else
+        OGS_FATAL(
+            "The code is not compiled with the Eigen unsupported modules.");
+#endif
+    }
+    if (auto smoothing =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__smoothing}
+        config->getConfigParameterOptional<int>("smoothing"))
+    {
+#ifdef USE_EIGEN_UNSUPPORTED
+        options.smoothing = *smoothing;
+#else
+        OGS_FATAL(
+            "The code is not compiled with the Eigen unsupported modules.");
+#endif
+    }
+    if (auto angle =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__angle}
+        config->getConfigParameterOptional<int>("angle"))
+    {
+#ifdef USE_EIGEN_UNSUPPORTED
+        options.angle = *angle;
+#else
+        OGS_FATAL(
+            "The code is not compiled with the Eigen unsupported modules.");
+#endif
+    }
+    if (auto residualupdate =
+            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__residual_update}
+        config->getConfigParameterOptional<int>("residual_update"))
+    {
+#ifdef USE_EIGEN_UNSUPPORTED
+        options.residualupdate = *residualupdate;
+#else
+        OGS_FATAL(
+            "The code is not compiled with the Eigen unsupported modules.");
+#endif
+    }
+    return {prefix, options};
+}
+}  // namespace MathLib
diff --git a/MathLib/LinAlg/Eigen/LinearSolverOptionsParser.h b/MathLib/LinAlg/Eigen/LinearSolverOptionsParser.h
index 87c2ed0df17..ef24f33e967 100644
--- a/MathLib/LinAlg/Eigen/LinearSolverOptionsParser.h
+++ b/MathLib/LinAlg/Eigen/LinearSolverOptionsParser.h
@@ -10,16 +10,15 @@
 
 #pragma once
 
-#include <memory>
-#include <vector>
-
-#include "BaseLib/ConfigTree.h"
-#include "BaseLib/Error.h"
 #include "EigenLinearSolver.h"
 #include "EigenOption.h"
-#include "MathLib/LinAlg/LinearSolverOptions.h"
 #include "MathLib/LinAlg/LinearSolverOptionsParser.h"
 
+namespace BaseLib
+{
+class ConfigTree;
+}
+
 namespace MathLib
 {
 template <>
@@ -34,132 +33,7 @@ struct LinearSolverOptionsParser<EigenLinearSolver> final
     /// string, the second item are all the options as an EigenOption object
     std::tuple<std::string, EigenOption> parseNameAndOptions(
         std::string const& prefix,
-        BaseLib::ConfigTree const* const solver_config) const
-    {
-        if (!solver_config)
-        {
-            return {prefix, EigenOption{}};
-        }
-
-        ignoreOtherLinearSolvers(*solver_config, "eigen");
-        //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen}
-        auto const config = solver_config->getConfigSubtreeOptional("eigen");
-        if (!config)
-        {
-            OGS_FATAL(
-                "OGS was compiled with Eigen but the config section in the "
-                "project file seems to be invalid");
-        }
-
-        EigenOption options;
-
-        if (auto solver_type =
-                //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__solver_type}
-            config->getConfigParameterOptional<std::string>("solver_type"))
-        {
-            options.solver_type =
-                MathLib::EigenOption::getSolverType(*solver_type);
-        }
-        if (auto precon_type =
-                //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__precon_type}
-            config->getConfigParameterOptional<std::string>("precon_type"))
-        {
-            options.precon_type =
-                MathLib::EigenOption::getPreconType(*precon_type);
-        }
-        if (auto error_tolerance =
-                //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__error_tolerance}
-            config->getConfigParameterOptional<double>("error_tolerance"))
-        {
-            options.error_tolerance = *error_tolerance;
-        }
-        if (auto max_iteration_step =
-                //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__max_iteration_step}
-            config->getConfigParameterOptional<int>("max_iteration_step"))
-        {
-            options.max_iterations = *max_iteration_step;
-        }
-        if (auto scaling =
-                //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__scaling}
-            config->getConfigParameterOptional<bool>("scaling"))
-        {
-#ifdef USE_EIGEN_UNSUPPORTED
-            options.scaling = *scaling;
-#else
-            OGS_FATAL(
-                "The code is not compiled with the Eigen unsupported modules. "
-                "scaling is not available.");
-#endif
-        }
-        if (auto restart =
-                //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__restart}
-            config->getConfigParameterOptional<int>("restart"))
-        {
-#ifdef USE_EIGEN_UNSUPPORTED
-            options.restart = *restart;
-#else
-            OGS_FATAL(
-                "The code is not compiled with the Eigen unsupported modules. "
-                "GMRES/GMRES option restart is not available.");
-#endif
-        }
-        if (auto l =
-            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__l}
-            config->getConfigParameterOptional<int>("l"))
-        {
-#ifdef USE_EIGEN_UNSUPPORTED
-            options.l = *l;
-#else
-            OGS_FATAL(
-                "The code is not compiled with the Eigen unsupported modules.");
-#endif
-        }
-        if (auto s =
-            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__s}
-            config->getConfigParameterOptional<int>("s"))
-        {
-#ifdef USE_EIGEN_UNSUPPORTED
-            options.s = *s;
-#else
-            OGS_FATAL(
-                "The code is not compiled with the Eigen unsupported modules.");
-#endif
-        }
-        if (auto smoothing =
-            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__smoothing}
-            config->getConfigParameterOptional<int>("smoothing"))
-        {
-#ifdef USE_EIGEN_UNSUPPORTED
-            options.smoothing = *smoothing;
-#else
-            OGS_FATAL(
-                "The code is not compiled with the Eigen unsupported modules.");
-#endif
-        }
-        if (auto angle =
-            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__angle}
-            config->getConfigParameterOptional<int>("angle"))
-        {
-#ifdef USE_EIGEN_UNSUPPORTED
-            options.angle = *angle;
-#else
-            OGS_FATAL(
-                "The code is not compiled with the Eigen unsupported modules.");
-#endif
-        }
-        if (auto residualupdate =
-            //! \ogs_file_param{prj__linear_solvers__linear_solver__eigen__residual_update}
-            config->getConfigParameterOptional<int>("residual_update"))
-        {
-#ifdef USE_EIGEN_UNSUPPORTED
-            options.residualupdate = *residualupdate;
-#else
-            OGS_FATAL(
-                "The code is not compiled with the Eigen unsupported modules.");
-#endif
-        }
-        return {prefix, options};
-    }
+        BaseLib::ConfigTree const* const solver_config) const;
 };
 
 }  // namespace MathLib
diff --git a/MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.cpp b/MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.cpp
new file mode 100644
index 00000000000..4066ef5c957
--- /dev/null
+++ b/MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.cpp
@@ -0,0 +1,42 @@
+/**
+ * \file
+ * \copyright
+ * Copyright (c) 2012-2022, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include "LinearSolverOptionsParser.h"
+
+#include "BaseLib/ConfigTree.h"
+#include "BaseLib/Logging.h"
+#include "MathLib/LinAlg/LinearSolverOptions.h"
+
+namespace MathLib
+{
+std::tuple<std::string, std::string>
+LinearSolverOptionsParser<EigenLisLinearSolver>::parseNameAndOptions(
+    std::string const& prefix, BaseLib::ConfigTree const* const config) const
+{
+    std::string lis_options = "-initx_zeros 0";
+
+    if (config)
+    {
+        ignoreOtherLinearSolvers(*config, "lis");
+        //! \ogs_file_param{prj__linear_solvers__linear_solver__lis}
+        if (auto s = config->getConfigParameterOptional<std::string>("lis"))
+        {
+            if (!s->empty())
+            {
+                lis_options += " " + *s;
+                INFO("Lis options: '{:s}'", lis_options);
+            }
+        }
+    }
+    return {prefix, lis_options};
+}
+}  // namespace MathLib
diff --git a/MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.h b/MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.h
index 7e9a99b72b4..c5b49a4b7e5 100644
--- a/MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.h
+++ b/MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.h
@@ -10,10 +10,11 @@
 
 #pragma once
 
-#include "BaseLib/ConfigTree.h"
-#include "BaseLib/Logging.h"
+namespace BaseLib
+{
+class ConfigTree;
+}
 #include "MathLib/LinAlg/EigenLis/EigenLisLinearSolver.h"
-#include "MathLib/LinAlg/LinearSolverOptions.h"
 #include "MathLib/LinAlg/LinearSolverOptionsParser.h"
 
 namespace MathLib
@@ -31,25 +32,7 @@ struct LinearSolverOptionsParser<EigenLisLinearSolver> final
     /// passed to LIS via lis_solver_set_options()
     std::tuple<std::string, std::string> parseNameAndOptions(
         std::string const& prefix,
-        BaseLib::ConfigTree const* const config) const
-    {
-        std::string lis_options = "-initx_zeros 0";
-
-        if (config)
-        {
-            ignoreOtherLinearSolvers(*config, "lis");
-            //! \ogs_file_param{prj__linear_solvers__linear_solver__lis}
-            if (auto s = config->getConfigParameterOptional<std::string>("lis"))
-            {
-                if (!s->empty())
-                {
-                    lis_options += " " + *s;
-                    INFO("Lis options: '{:s}'", lis_options);
-                }
-            }
-        }
-        return {prefix, lis_options};
-    }
+        BaseLib::ConfigTree const* const config) const;
 };
 
 }  // namespace MathLib
diff --git a/MathLib/LinAlg/PETSc/LinearSolverOptionsParser.cpp b/MathLib/LinAlg/PETSc/LinearSolverOptionsParser.cpp
new file mode 100644
index 00000000000..ad9dd51a463
--- /dev/null
+++ b/MathLib/LinAlg/PETSc/LinearSolverOptionsParser.cpp
@@ -0,0 +1,52 @@
+/**
+ * \file
+ * \copyright
+ * Copyright (c) 2012-2022, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "LinearSolverOptionsParser.h"
+
+#include "BaseLib/ConfigTree.h"
+#include "MathLib/LinAlg/LinearSolverOptions.h"
+
+namespace MathLib
+{
+std::tuple<std::string, std::string>
+LinearSolverOptionsParser<PETScLinearSolver>::parseNameAndOptions(
+    std::string solver_prefix, BaseLib::ConfigTree const* const config) const
+{
+    // Insert options into petsc database. Default options are given in the
+    // string below.
+    std::string petsc_options =
+        "-ksp_type cg -pc_type bjacobi -ksp_rtol 1e-16 -ksp_max_it 10000";
+
+    if (config)
+    {
+        ignoreOtherLinearSolvers(*config, "petsc");
+
+        //! \ogs_file_param{prj__linear_solvers__linear_solver__petsc}
+        if (auto const subtree = config->getConfigSubtreeOptional("petsc"))
+        {
+            if (auto const parameters =
+                    //! \ogs_file_param{prj__linear_solvers__linear_solver__petsc__parameters}
+                subtree->getConfigParameterOptional<std::string>("parameters"))
+            {
+                petsc_options = *parameters;
+            }
+
+            if (auto const pre =
+                    //! \ogs_file_param{prj__linear_solvers__linear_solver__petsc__prefix}
+                subtree->getConfigParameterOptional<std::string>("prefix"))
+            {
+                if (!pre->empty())
+                    solver_prefix = *pre + "_";
+            }
+        }
+    }
+    return {solver_prefix, petsc_options};
+}
+}  // namespace MathLib
diff --git a/MathLib/LinAlg/PETSc/LinearSolverOptionsParser.h b/MathLib/LinAlg/PETSc/LinearSolverOptionsParser.h
index 3ab173875a6..f0e09013180 100644
--- a/MathLib/LinAlg/PETSc/LinearSolverOptionsParser.h
+++ b/MathLib/LinAlg/PETSc/LinearSolverOptionsParser.h
@@ -10,11 +10,14 @@
 
 #pragma once
 
-#include "BaseLib/ConfigTree.h"
-#include "MathLib/LinAlg/LinearSolverOptions.h"
 #include "MathLib/LinAlg/LinearSolverOptionsParser.h"
 #include "MathLib/LinAlg/PETSc/PETScLinearSolver.h"
 
+namespace BaseLib
+{
+class ConfigTree;
+}
+
 namespace MathLib
 {
 template <>
@@ -30,39 +33,7 @@ struct LinearSolverOptionsParser<PETScLinearSolver> final
     /// options database
     std::tuple<std::string, std::string> parseNameAndOptions(
         std::string solver_prefix,
-        BaseLib::ConfigTree const* const config) const
-    {
-        // Insert options into petsc database. Default options are given in the
-        // string below.
-        std::string petsc_options =
-            "-ksp_type cg -pc_type bjacobi -ksp_rtol 1e-16 -ksp_max_it 10000";
-
-        if (config)
-        {
-            ignoreOtherLinearSolvers(*config, "petsc");
-
-            //! \ogs_file_param{prj__linear_solvers__linear_solver__petsc}
-            if (auto const subtree = config->getConfigSubtreeOptional("petsc"))
-            {
-                if (auto const parameters =
-                        //! \ogs_file_param{prj__linear_solvers__linear_solver__petsc__parameters}
-                    subtree->getConfigParameterOptional<std::string>(
-                        "parameters"))
-                {
-                    petsc_options = *parameters;
-                }
-
-                if (auto const pre =
-                        //! \ogs_file_param{prj__linear_solvers__linear_solver__petsc__prefix}
-                    subtree->getConfigParameterOptional<std::string>("prefix"))
-                {
-                    if (!pre->empty())
-                        solver_prefix = *pre + "_";
-                }
-            }
-        }
-        return {solver_prefix, petsc_options};
-    }
+        BaseLib::ConfigTree const* const config) const;
 };
 
 }  // namespace MathLib
-- 
GitLab