LCOV - code coverage report
Current view: top level - include/solvers - eigen_sparse_linear_solver.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 9 12 75.0 %
Date: 2025-08-19 19:27:09 Functions: 4 8 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : #ifndef LIBMESH_EIGEN_SPARSE_LINEAR_SOLVER_H
      21             : #define LIBMESH_EIGEN_SPARSE_LINEAR_SOLVER_H
      22             : 
      23             : #include "libmesh/libmesh_common.h"
      24             : 
      25             : #ifdef LIBMESH_HAVE_EIGEN
      26             : 
      27             : // Eigen includes
      28             : 
      29             : // Local includes
      30             : #include "libmesh/linear_solver.h"
      31             : #include "libmesh/eigen_sparse_vector.h"
      32             : #include "libmesh/eigen_sparse_matrix.h"
      33             : #include "libmesh/enum_convergence_flags.h" // The build_map() function uses these.
      34             : 
      35             : 
      36             : namespace libMesh
      37             : {
      38             : 
      39             : /**
      40             :  * This class provides an interface to Eigen
      41             :  * iterative solvers that is compatible with the \p libMesh
      42             :  * \p LinearSolver<>
      43             :  *
      44             :  * \author Benjamin Kirk
      45             :  * \date 2013
      46             :  */
      47             : template <typename T>
      48             : class EigenSparseLinearSolver : public LinearSolver<T>
      49             : {
      50             : public:
      51             :   /**
      52             :    *  Constructor. Initializes Eigen data structures
      53             :    */
      54             :   EigenSparseLinearSolver (const libMesh::Parallel::Communicator & comm_in);
      55             : 
      56             :   /**
      57             :    * Destructor.
      58             :    */
      59             :   ~EigenSparseLinearSolver ();
      60             : 
      61             :   /**
      62             :    * Release all memory and clear data structures.
      63             :    */
      64             :   virtual void clear () override;
      65             : 
      66             :   /**
      67             :    * Initialize data structures if not done so already.
      68             :    */
      69             :   virtual void init (const char * name=nullptr) override;
      70             : 
      71             :   /**
      72             :    * Call the Eigen solver
      73             :    */
      74             :   virtual std::pair<unsigned int, Real>
      75             :   solve (SparseMatrix<T> & matrix,
      76             :          NumericVector<T> & solution,
      77             :          NumericVector<T> & rhs,
      78             :          const std::optional<double> tol = std::nullopt,
      79             :          const std::optional<unsigned int> m_its = std::nullopt) override;
      80             : 
      81             :   /**
      82             :    * Call the Eigen solver to solve A^T x = b
      83             :    */
      84             :   virtual std::pair<unsigned int, Real>
      85             :   adjoint_solve (SparseMatrix<T> & matrix,
      86             :                  NumericVector<T> & solution,
      87             :                  NumericVector<T> & rhs,
      88             :                  const std::optional<double> tol = std::nullopt,
      89             :                  const std::optional<unsigned int> m_its = std::nullopt) override;
      90             : 
      91             :   /**
      92             :    * Call the Eigen solver
      93             :    */
      94             :   virtual std::pair<unsigned int, Real>
      95             :   solve (SparseMatrix<T> & matrix,
      96             :          SparseMatrix<T> & pc,
      97             :          NumericVector<T> & solution,
      98             :          NumericVector<T> & rhs,
      99             :          const std::optional<double> tol = std::nullopt,
     100             :          const std::optional<unsigned int> m_its = std::nullopt) override;
     101             : 
     102             :   /**
     103             :    * This function solves a system whose matrix is a shell matrix.
     104             :    */
     105             :   virtual std::pair<unsigned int, Real>
     106             :   solve (const ShellMatrix<T> & shell_matrix,
     107             :          NumericVector<T> & solution_in,
     108             :          NumericVector<T> & rhs_in,
     109             :          const std::optional<double> tol = std::nullopt,
     110             :          const std::optional<unsigned int> m_its = std::nullopt) override;
     111             : 
     112             :   /**
     113             :    * This function solves a system whose matrix is a shell matrix, but
     114             :    * a sparse matrix is used as preconditioning matrix, this allowing
     115             :    * other preconditioners than JACOBI.
     116             :    */
     117             :   virtual std::pair<unsigned int, Real>
     118             :   solve (const ShellMatrix<T> & shell_matrix,
     119             :          const SparseMatrix<T> & precond_matrix,
     120             :          NumericVector<T> & solution_in,
     121             :          NumericVector<T> & rhs_in,
     122             :          const std::optional<double> tol = std::nullopt,
     123             :          const std::optional<unsigned int> m_its = std::nullopt) override;
     124             : 
     125             :   /**
     126             :    * \returns The solver's convergence flag
     127             :    */
     128             :   virtual LinearConvergenceReason get_converged_reason() const override;
     129             : 
     130             : private:
     131             : 
     132             :   /**
     133             :    * Tells Eigen to use the user-specified preconditioner stored in
     134             :    * \p _preconditioner_type
     135             :    */
     136             :   void set_eigen_preconditioner_type ();
     137             : 
     138             :   /**
     139             :    * Store the result of the last solve.
     140             :    */
     141             :   Eigen::ComputationInfo _comp_info;
     142             : 
     143             :   /**
     144             :    * Static map between Eigen ComputationInfo enumerations and libMesh
     145             :    * LinearConvergenceReason enumerations.
     146             :    */
     147             :   static std::map<Eigen::ComputationInfo, LinearConvergenceReason> _convergence_reasons;
     148             : 
     149             :   /**
     150             :    * Static function used to initialize _convergence_reasons map
     151             :    */
     152       16389 :   static std::map<Eigen::ComputationInfo, LinearConvergenceReason> build_map()
     153             :   {
     154         462 :     std::map<Eigen::ComputationInfo, LinearConvergenceReason> ret;
     155       16389 :     ret[Eigen::Success]        = CONVERGED_ITS;
     156       16389 :     ret[Eigen::NumericalIssue] = DIVERGED_BREAKDOWN;
     157       16389 :     ret[Eigen::NoConvergence]  = DIVERGED_ITS;
     158       16389 :     ret[Eigen::InvalidInput]   = DIVERGED_NULL;
     159       16389 :     return ret;
     160             :   }
     161             : };
     162             : 
     163             : 
     164             : 
     165             : // Call the class-static function to define the class-static member.
     166             : // Since it's a template class, you actually do this in the header,
     167             : // not the source file.
     168             : template <typename T>
     169             : std::map<Eigen::ComputationInfo, LinearConvergenceReason>
     170             : EigenSparseLinearSolver<T>::_convergence_reasons = EigenSparseLinearSolver<T>::build_map();
     171             : 
     172             : 
     173             : 
     174             : template <typename T>
     175             : inline
     176         552 : EigenSparseLinearSolver<T>::~EigenSparseLinearSolver ()
     177             : {
     178           0 :   this->clear ();
     179         552 : }
     180             : 
     181             : 
     182             : 
     183             : template <typename T>
     184             : inline
     185             : std::pair<unsigned int, Real>
     186           0 : EigenSparseLinearSolver<T>::solve (SparseMatrix<T> &,
     187             :                                    SparseMatrix<T> &,
     188             :                                    NumericVector<T> &,
     189             :                                    NumericVector<T> &,
     190             :                                    const std::optional<double>,
     191             :                                    const std::optional<unsigned int>)
     192             : {
     193           0 :   libmesh_error_msg("ERROR: Eigen does not support a user-supplied preconditioner!");
     194             : 
     195             :   return std::pair<unsigned int, Real>();
     196             : }
     197             : 
     198             : } // namespace libMesh
     199             : 
     200             : #endif // #ifdef LIBMESH_HAVE_EIGEN
     201             : #endif // LIBMESH_EIGEN_SPARSE_LINEAR_SOLVER_H

Generated by: LCOV version 1.14