LCOV - code coverage report
Current view: top level - include/systems - implicit_system.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 1 6 16.7 %
Date: 2025-08-19 19:27:09 Functions: 1 5 20.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_IMPLICIT_SYSTEM_H
      21             : #define LIBMESH_IMPLICIT_SYSTEM_H
      22             : 
      23             : // Local Includes
      24             : #include "libmesh/explicit_system.h"
      25             : 
      26             : // C++ includes
      27             : #include <cstddef>
      28             : #include <memory>
      29             : 
      30             : namespace libMesh
      31             : {
      32             : 
      33             : // Forward declarations
      34             : template <typename T> class LinearSolver;
      35             : class StaticCondensation;
      36             : 
      37             : /**
      38             :  * \brief Manages consistently variables, degrees of freedom, coefficient
      39             :  * vectors, and matrices for implicit systems.
      40             :  *
      41             :  * Implicit systems are characterized by the need to solve the (non-)linear
      42             :  * system Ax=b. This class provides, in addition to the ExplicitSystem class,
      43             :  * storage for sparse matrices. Hence this System provides means to manage a
      44             :  * right hand side vector and a sparse matrix. In addition, further matrices
      45             :  * can be managed using the ImplicitSystem::add_matrix method.
      46             :  *
      47             :  * This class provieds *no* means to solve the implicit system. This
      48             :  * functionality is provided, e.g., by the LinearImplicitSystem or the
      49             :  * NonlinearImplicitSystem class.
      50             :  *
      51             :  * \note Additional vectors/matrices can be added via parent class
      52             :  * interfaces.
      53             :  *
      54             :  * \author Benjamin S. Kirk
      55             :  * \date 2004
      56             :  */
      57        1378 : class ImplicitSystem : public ExplicitSystem
      58             : {
      59             : public:
      60             : 
      61             :   /**
      62             :    * Constructor.
      63             :    */
      64             :   ImplicitSystem (EquationSystems & es,
      65             :                   const std::string & name,
      66             :                   const unsigned int number);
      67             : 
      68             :   /**
      69             :    * Special functions.
      70             :    * - This class has the same restrictions/defaults as its base class.
      71             :    * - The destructor is defaulted out-of-line.
      72             :    */
      73             :   ImplicitSystem (const ImplicitSystem &) = delete;
      74             :   ImplicitSystem & operator= (const ImplicitSystem &) = delete;
      75             :   ImplicitSystem (ImplicitSystem &&) = default;
      76             :   ImplicitSystem & operator= (ImplicitSystem &&) = delete;
      77             :   virtual ~ImplicitSystem ();
      78             : 
      79             :   /**
      80             :    * The type of system.
      81             :    */
      82             :   typedef ImplicitSystem sys_type;
      83             : 
      84             :   /**
      85             :    * \returns A reference to *this.
      86             :    */
      87             :   sys_type & system () { return *this; }
      88             : 
      89             :   /**
      90             :    * The type of the parent.
      91             :    */
      92             :   typedef ExplicitSystem Parent;
      93             : 
      94             :   /**
      95             :    * Clear all the data structures associated with
      96             :    * the system.
      97             :    */
      98             :   virtual void clear () override;
      99             : 
     100             :   /**
     101             :    * Prepares \p matrix and \p rhs for system assembly, then calls
     102             :    * user assembly function.
     103             :    * Can be overridden in derived classes.
     104             :    */
     105             :   virtual void assemble () override;
     106             : 
     107             :   /**
     108             :    * Avoids use of any cached data that might affect any solve result.  Should
     109             :    * be overridden in derived systems.
     110             :    */
     111             :   virtual void disable_cache () override;
     112             : 
     113             :   /**
     114             :    * \returns \p "Implicit".  Helps in identifying
     115             :    * the system type in an equation system file.
     116             :    */
     117           0 :   virtual std::string system_type () const override { return "Implicit"; }
     118             : 
     119             :   /**
     120             :    * \returns A dumb pointer to a local std::unique_ptr<LinearSolver>
     121             :    * member which can be used in adjoint and/or sensitivity solves.
     122             :    *
     123             :    * To mimic the previous behavior of this function, if the
     124             :    * linear_solver member is already initialized when this function is
     125             :    * called, this function first clears it. That is, no attempt is
     126             :    * made to reuse an existing LinearSolver object. The user MUST NOT
     127             :    * attempt to clean up this pointer, otherwise the std::unique_ptr
     128             :    * held by this class will likely become corrupted.
     129             :    *
     130             :    * This function is virtual so it can be overridden in derived
     131             :    * classes if necessary, however most will probably just want to use
     132             :    * the base class behavior.
     133             :    */
     134             :   virtual LinearSolver<Number> * get_linear_solver() const;
     135             : 
     136             :   /**
     137             :    * \returns An integer corresponding to the upper iteration count
     138             :    * limit and a Real corresponding to the convergence tolerance to
     139             :    * be used in linear adjoint and/or sensitivity solves
     140             :    */
     141             :   virtual std::pair<unsigned int, Real>
     142             :   get_linear_solve_parameters() const;
     143             : 
     144             : #ifdef LIBMESH_ENABLE_DEPRECATED
     145             :   /**
     146             :    * Currently a no-op.
     147             :    *
     148             :    * \deprecated This function no longer needs to be called, since
     149             :    * get_linear_solver() no longer returns a heap-allocated dumb
     150             :    * pointer.
     151             :    */
     152             :   virtual void release_linear_solver(LinearSolver<Number> *) const;
     153             : #endif // LIBMESH_ENABLE_DEPRECATED
     154             : 
     155             :   /**
     156             :    * Assembles a residual in \p rhs and/or a jacobian in \p matrix,
     157             :    * as requested.
     158             :    *
     159             :    * This is undefined in ImplicitSystem; subclasses each have their
     160             :    * own way of handling assembly.
     161             :    */
     162           0 :   virtual void assembly (bool /* get_residual */,
     163             :                          bool /* get_jacobian */,
     164             :                          bool /* apply_heterogeneous_constraints */ = false,
     165             :                          bool /* apply_no_constraints */ = false)
     166           0 :   { libmesh_not_implemented(); }
     167             : 
     168             :   /**
     169             :    * Residual parameter derivative function.
     170             :    *
     171             :    * Uses finite differences by default.
     172             :    *
     173             :    * This will assemble the sensitivity rhs vectors to hold
     174             :    * -(partial R / partial p_i), making them ready to solve
     175             :    * the forward sensitivity equation.
     176             :    *
     177             :    * Can be overridden in derived classes.
     178             :    */
     179             :   virtual void assemble_residual_derivatives (const ParameterVector & parameters) override;
     180             : 
     181             :   /**
     182             :    * For explicit systems, just assemble and solve the system A*x=b.
     183             :    * Should be overridden in derived systems to provide a solver for the
     184             :    * system.
     185             :    */
     186           0 :   virtual void solve () override
     187           0 :   { libmesh_not_implemented(); }
     188             : 
     189             :   /**
     190             :    * Assembles & solves the linear system(s) (dR/du)*u_p = -dR/dp, for
     191             :    * those parameters contained within \p parameters.
     192             :    *
     193             :    * \returns A pair with the total number of linear iterations
     194             :    * performed and the (sum of the) final residual norms
     195             :    */
     196             :   virtual std::pair<unsigned int, Real>
     197             :   sensitivity_solve (const ParameterVector & parameters) override;
     198             : 
     199             :   /**
     200             :    * Assembles & solves the linear system(s) (dR/du)*u_w = sum(w_p*-dR/dp), for
     201             :    * those parameters p contained within \p parameters weighted by the
     202             :    * values w_p found within \p weights.
     203             :    *
     204             :    * \returns A pair with the total number of linear iterations
     205             :    * performed and the (sum of the) final residual norms
     206             :    */
     207             :   virtual std::pair<unsigned int, Real>
     208             :   weighted_sensitivity_solve (const ParameterVector & parameters,
     209             :                               const ParameterVector & weights) override;
     210             : 
     211             :   /**
     212             :    * Assembles & solves the linear system (dR/du)^T*z = dq/du, for
     213             :    * those quantities of interest q specified by \p qoi_indices.
     214             :    *
     215             :    * Leave \p qoi_indices empty to solve all adjoint problems.
     216             :    *
     217             :    * \returns A pair with the total number of linear iterations
     218             :    * performed and the (sum of the) final residual norms
     219             :    */
     220             :   virtual std::pair<unsigned int, Real>
     221             :   adjoint_solve (const QoISet & qoi_indices = QoISet()) override;
     222             : 
     223             :   /**
     224             :    * Assembles & solves the linear system(s)
     225             :    * (dR/du)^T*z_w = sum(w_p*(d^2q/dudp - d^2R/dudp*z)), for those
     226             :    * parameters p contained within \p parameters, weighted by the
     227             :    * values w_p found within \p weights.
     228             :    *
     229             :    * Assumes that adjoint_solve has already calculated z for each qoi
     230             :    * in \p qoi_indices.
     231             :    *
     232             :    * \returns A pair with the total number of linear iterations
     233             :    * performed and the (sum of the) final residual norms
     234             :    */
     235             :   virtual std::pair<unsigned int, Real>
     236             :   weighted_sensitivity_adjoint_solve (const ParameterVector & parameters,
     237             :                                       const ParameterVector & weights,
     238             :                                       const QoISet & qoi_indices = QoISet()) override;
     239             : 
     240             :   /**
     241             :    * Solves for the derivative of each of the system's quantities of
     242             :    * interest q in \p qoi[qoi_indices] with respect to each parameter in
     243             :    * \p parameters, placing the result for qoi \p i and parameter \p j
     244             :    * into \p sensitivities[i][j].
     245             :    *
     246             :    * Uses adjoint_solve() and the adjoint sensitivity method.
     247             :    *
     248             :    * Currently uses finite differenced derivatives (partial q /
     249             :    * partial p) and (partial R / partial p).
     250             :    */
     251             :   virtual void adjoint_qoi_parameter_sensitivity (const QoISet & qoi_indices,
     252             :                                                   const ParameterVector & parameters,
     253             :                                                   SensitivityData & sensitivities) override;
     254             : 
     255             :   /**
     256             :    * Solves for the derivative of each of the system's quantities of
     257             :    * interest q in \p qoi[qoi_indices] with respect to each parameter in
     258             :    * \p parameters, placing the result for qoi \p i and parameter \p j
     259             :    * into \p sensitivities[i][j].
     260             :    *
     261             :    * Uses the forward sensitivity method.
     262             :    *
     263             :    * Currently uses finite differenced derivatives (partial q /
     264             :    * partial p) and (partial R / partial p).
     265             :    */
     266             :   virtual void forward_qoi_parameter_sensitivity (const QoISet & qoi_indices,
     267             :                                                   const ParameterVector & parameters,
     268             :                                                   SensitivityData & sensitivities) override;
     269             : 
     270             :   /**
     271             :    * For each of the system's quantities of interest q in
     272             :    * \p qoi[qoi_indices], and for a vector of parameters p, the
     273             :    * parameter sensitivity Hessian H_ij is defined as
     274             :    * H_ij = (d^2 q)/(d p_i d p_j)
     275             :    * This Hessian is the output of this method, where for each q_i,
     276             :    * H_jk is stored in \p hessian.second_derivative(i,j,k).
     277             :    *
     278             :    * Note that in some cases only
     279             :    * \link current_local_solution \endlink is used during assembly,
     280             :    * and, therefore, if \link solution \endlink has been altered
     281             :    * without \link update() \endlink being called, then the
     282             :    * user must call \link update() \endlink before calling
     283             :    * this function.
     284             :    */
     285             :   virtual void qoi_parameter_hessian(const QoISet & qoi_indices,
     286             :                                      const ParameterVector & parameters,
     287             :                                      SensitivityData & hessian) override;
     288             : 
     289             :   /**
     290             :    * For each of the system's quantities of interest q in
     291             :    * \p qoi[qoi_indices], and for a vector of parameters p, the
     292             :    * parameter sensitivity Hessian H_ij is defined as
     293             :    * H_ij = (d^2 q)/(d p_i d p_j)
     294             :    * The Hessian-vector product, for a vector v_k in parameter space, is
     295             :    * S_j = H_jk v_k
     296             :    * This product is the output of this method, where for each q_i,
     297             :    * S_j is stored in \p sensitivities[i][j].
     298             :    */
     299             :   virtual void qoi_parameter_hessian_vector_product(const QoISet & qoi_indices,
     300             :                                                     const ParameterVector & parameters,
     301             :                                                     const ParameterVector & vector,
     302             :                                                     SensitivityData & product) override;
     303             : 
     304             :   /**
     305             :    * \returns A const reference to the system's primary matrix.
     306             :    */
     307             :   const SparseMatrix<Number> & get_system_matrix() const;
     308             : 
     309             :   /**
     310             :    * \returns A reference to the system's primary matrix.
     311             :    */
     312             :   SparseMatrix<Number> & get_system_matrix();
     313             : 
     314             :   /**
     315             :    * The system matrix.  Implicit systems are characterized by
     316             :    * the need to solve the linear system Ax=b.  This is the
     317             :    * system matrix A.
     318             :    *
     319             :    * Public access to this member variable will be deprecated in
     320             :    * the future! Use get_system_matrix() instead.
     321             :    */
     322             :   SparseMatrix<Number> * matrix;
     323             : 
     324             :   /**
     325             :    * By default, the system will zero out the matrix and the right hand side.
     326             :    * If this flag is false, it is the responsibility of the client code
     327             :    * to take care of setting these to zero before assembly begins
     328             :    */
     329             :   bool zero_out_matrix_and_rhs;
     330             : 
     331             :   /**
     332             :    * This class handles all the details of interfacing with various
     333             :    * linear algebra packages like PETSc or LASPACK.  This is a public
     334             :    * member for backwards compatibility reasons, but in general it's
     335             :    * better to use get_linear_solver() to access this member, since
     336             :    * that function will also handle initialization if it hasn't
     337             :    * already been taken care of.
     338             :    */
     339             :   mutable std::unique_ptr<LinearSolver<Number>> linear_solver;
     340             : 
     341             :   virtual void create_static_condensation() override;
     342             : 
     343             :   /**
     344             :    * \returns The static condensation system matrix
     345             :    */
     346             :   StaticCondensation & get_static_condensation();
     347             : 
     348             : protected:
     349             :   /**
     350             :    * Adds the system matrix
     351             :    */
     352             :   virtual void add_matrices() override;
     353             : 
     354             :   /**
     355             :    * Sets up the static condensation preconditioner for the supplied \p solver
     356             :    */
     357             :   template <typename T>
     358             :   void setup_static_condensation_preconditioner(T & solver);
     359             : 
     360             : private:
     361             :   /**
     362             :    * Create the static condensation system matrix
     363             :    */
     364             :    void create_static_condensation_system_matrix();
     365             : 
     366             :   /**
     367             :    * The system matrix for static condensation problems
     368             :    */
     369             :    StaticCondensation * _sc_system_matrix;
     370             : };
     371             : 
     372             : inline
     373             : StaticCondensation & ImplicitSystem::get_static_condensation()
     374             : {
     375             :   libmesh_assert(_sc_system_matrix);
     376             :   return *_sc_system_matrix;
     377             : }
     378             : 
     379             : } // namespace libMesh
     380             : 
     381             : #endif // LIBMESH_IMPLICIT_SYSTEM_H

Generated by: LCOV version 1.14