LCOV - code coverage report
Current view: top level - include/systems - implicit_system.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4308 (b969c4) with base 7aa2c3 Lines: 1 6 16.7 %
Date: 2025-11-07 13:38: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        1466 : 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             :   /**
     145             :    * Assembles a residual in \p rhs and/or a jacobian in \p matrix,
     146             :    * as requested.
     147             :    *
     148             :    * This is undefined in ImplicitSystem; subclasses each have their
     149             :    * own way of handling assembly.
     150             :    */
     151           0 :   virtual void assembly (bool /* get_residual */,
     152             :                          bool /* get_jacobian */,
     153             :                          bool /* apply_heterogeneous_constraints */ = false,
     154             :                          bool /* apply_no_constraints */ = false)
     155           0 :   { libmesh_not_implemented(); }
     156             : 
     157             :   /**
     158             :    * Residual parameter derivative function.
     159             :    *
     160             :    * Uses finite differences by default.
     161             :    *
     162             :    * This will assemble the sensitivity rhs vectors to hold
     163             :    * -(partial R / partial p_i), making them ready to solve
     164             :    * the forward sensitivity equation.
     165             :    *
     166             :    * Can be overridden in derived classes.
     167             :    */
     168             :   virtual void assemble_residual_derivatives (const ParameterVector & parameters) override;
     169             : 
     170             :   /**
     171             :    * For explicit systems, just assemble and solve the system A*x=b.
     172             :    * Should be overridden in derived systems to provide a solver for the
     173             :    * system.
     174             :    */
     175           0 :   virtual void solve () override
     176           0 :   { libmesh_not_implemented(); }
     177             : 
     178             :   /**
     179             :    * Assembles & solves the linear system(s) (dR/du)*u_p = -dR/dp, for
     180             :    * those parameters contained within \p parameters.
     181             :    *
     182             :    * \returns A pair with the total number of linear iterations
     183             :    * performed and the (sum of the) final residual norms
     184             :    */
     185             :   virtual std::pair<unsigned int, Real>
     186             :   sensitivity_solve (const ParameterVector & parameters) override;
     187             : 
     188             :   /**
     189             :    * Assembles & solves the linear system(s) (dR/du)*u_w = sum(w_p*-dR/dp), for
     190             :    * those parameters p contained within \p parameters weighted by the
     191             :    * values w_p found within \p weights.
     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             :   weighted_sensitivity_solve (const ParameterVector & parameters,
     198             :                               const ParameterVector & weights) override;
     199             : 
     200             :   /**
     201             :    * Assembles & solves the linear system (dR/du)^T*z = dq/du, for
     202             :    * those quantities of interest q specified by \p qoi_indices.
     203             :    *
     204             :    * Leave \p qoi_indices empty to solve all adjoint problems.
     205             :    *
     206             :    * \returns A pair with the total number of linear iterations
     207             :    * performed and the (sum of the) final residual norms
     208             :    */
     209             :   virtual std::pair<unsigned int, Real>
     210             :   adjoint_solve (const QoISet & qoi_indices = QoISet()) override;
     211             : 
     212             :   /**
     213             :    * Assembles & solves the linear system(s)
     214             :    * (dR/du)^T*z_w = sum(w_p*(d^2q/dudp - d^2R/dudp*z)), for those
     215             :    * parameters p contained within \p parameters, weighted by the
     216             :    * values w_p found within \p weights.
     217             :    *
     218             :    * Assumes that adjoint_solve has already calculated z for each qoi
     219             :    * in \p qoi_indices.
     220             :    *
     221             :    * \returns A pair with the total number of linear iterations
     222             :    * performed and the (sum of the) final residual norms
     223             :    */
     224             :   virtual std::pair<unsigned int, Real>
     225             :   weighted_sensitivity_adjoint_solve (const ParameterVector & parameters,
     226             :                                       const ParameterVector & weights,
     227             :                                       const QoISet & qoi_indices = QoISet()) override;
     228             : 
     229             :   /**
     230             :    * Solves for the derivative of each of the system's quantities of
     231             :    * interest q in \p qoi[qoi_indices] with respect to each parameter in
     232             :    * \p parameters, placing the result for qoi \p i and parameter \p j
     233             :    * into \p sensitivities[i][j].
     234             :    *
     235             :    * Uses adjoint_solve() and the adjoint sensitivity method.
     236             :    *
     237             :    * Currently uses finite differenced derivatives (partial q /
     238             :    * partial p) and (partial R / partial p).
     239             :    */
     240             :   virtual void adjoint_qoi_parameter_sensitivity (const QoISet & qoi_indices,
     241             :                                                   const ParameterVector & parameters,
     242             :                                                   SensitivityData & sensitivities) override;
     243             : 
     244             :   /**
     245             :    * Solves for the derivative of each of the system's quantities of
     246             :    * interest q in \p qoi[qoi_indices] with respect to each parameter in
     247             :    * \p parameters, placing the result for qoi \p i and parameter \p j
     248             :    * into \p sensitivities[i][j].
     249             :    *
     250             :    * Uses the forward sensitivity method.
     251             :    *
     252             :    * Currently uses finite differenced derivatives (partial q /
     253             :    * partial p) and (partial R / partial p).
     254             :    */
     255             :   virtual void forward_qoi_parameter_sensitivity (const QoISet & qoi_indices,
     256             :                                                   const ParameterVector & parameters,
     257             :                                                   SensitivityData & sensitivities) override;
     258             : 
     259             :   /**
     260             :    * For each of the system's quantities of interest q in
     261             :    * \p qoi[qoi_indices], and for a vector of parameters p, the
     262             :    * parameter sensitivity Hessian H_ij is defined as
     263             :    * H_ij = (d^2 q)/(d p_i d p_j)
     264             :    * This Hessian is the output of this method, where for each q_i,
     265             :    * H_jk is stored in \p hessian.second_derivative(i,j,k).
     266             :    *
     267             :    * Note that in some cases only
     268             :    * \link current_local_solution \endlink is used during assembly,
     269             :    * and, therefore, if \link solution \endlink has been altered
     270             :    * without \link update() \endlink being called, then the
     271             :    * user must call \link update() \endlink before calling
     272             :    * this function.
     273             :    */
     274             :   virtual void qoi_parameter_hessian(const QoISet & qoi_indices,
     275             :                                      const ParameterVector & parameters,
     276             :                                      SensitivityData & hessian) override;
     277             : 
     278             :   /**
     279             :    * For each of the system's quantities of interest q in
     280             :    * \p qoi[qoi_indices], and for a vector of parameters p, the
     281             :    * parameter sensitivity Hessian H_ij is defined as
     282             :    * H_ij = (d^2 q)/(d p_i d p_j)
     283             :    * The Hessian-vector product, for a vector v_k in parameter space, is
     284             :    * S_j = H_jk v_k
     285             :    * This product is the output of this method, where for each q_i,
     286             :    * S_j is stored in \p sensitivities[i][j].
     287             :    */
     288             :   virtual void qoi_parameter_hessian_vector_product(const QoISet & qoi_indices,
     289             :                                                     const ParameterVector & parameters,
     290             :                                                     const ParameterVector & vector,
     291             :                                                     SensitivityData & product) override;
     292             : 
     293             :   /**
     294             :    * \returns A const reference to the system's primary matrix.
     295             :    */
     296             :   const SparseMatrix<Number> & get_system_matrix() const;
     297             : 
     298             :   /**
     299             :    * \returns A reference to the system's primary matrix.
     300             :    */
     301             :   SparseMatrix<Number> & get_system_matrix();
     302             : 
     303             :   /**
     304             :    * The system matrix.  Implicit systems are characterized by
     305             :    * the need to solve the linear system Ax=b.  This is the
     306             :    * system matrix A.
     307             :    *
     308             :    * Public access to this member variable will be deprecated in
     309             :    * the future! Use get_system_matrix() instead.
     310             :    */
     311             :   SparseMatrix<Number> * matrix;
     312             : 
     313             :   /**
     314             :    * By default, the system will zero out the matrix and the right hand side.
     315             :    * If this flag is false, it is the responsibility of the client code
     316             :    * to take care of setting these to zero before assembly begins
     317             :    */
     318             :   bool zero_out_matrix_and_rhs;
     319             : 
     320             :   /**
     321             :    * This class handles all the details of interfacing with various
     322             :    * linear algebra packages like PETSc or LASPACK.  This is a public
     323             :    * member for backwards compatibility reasons, but in general it's
     324             :    * better to use get_linear_solver() to access this member, since
     325             :    * that function will also handle initialization if it hasn't
     326             :    * already been taken care of.
     327             :    */
     328             :   mutable std::unique_ptr<LinearSolver<Number>> linear_solver;
     329             : 
     330             :   virtual void create_static_condensation() override;
     331             : 
     332             :   /**
     333             :    * \returns The static condensation system matrix
     334             :    */
     335             :   StaticCondensation & get_static_condensation();
     336             : 
     337             : protected:
     338             :   /**
     339             :    * Adds the system matrix
     340             :    */
     341             :   virtual void add_matrices() override;
     342             : 
     343             :   /**
     344             :    * Sets up the static condensation preconditioner for the supplied \p solver
     345             :    */
     346             :   template <typename T>
     347             :   void setup_static_condensation_preconditioner(T & solver);
     348             : 
     349             : private:
     350             :   /**
     351             :    * Create the static condensation system matrix
     352             :    */
     353             :    void create_static_condensation_system_matrix();
     354             : 
     355             :   /**
     356             :    * The system matrix for static condensation problems
     357             :    */
     358             :    StaticCondensation * _sc_system_matrix;
     359             : };
     360             : 
     361             : inline
     362             : StaticCondensation & ImplicitSystem::get_static_condensation()
     363             : {
     364             :   libmesh_assert(_sc_system_matrix);
     365             :   return *_sc_system_matrix;
     366             : }
     367             : 
     368             : } // namespace libMesh
     369             : 
     370             : #endif // LIBMESH_IMPLICIT_SYSTEM_H

Generated by: LCOV version 1.14