LCOV - code coverage report
Current view: top level - include/solvers - time_solver.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 8 9 88.9 %
Date: 2025-08-19 19:27:09 Functions: 6 8 75.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_TIME_SOLVER_H
      21             : #define LIBMESH_TIME_SOLVER_H
      22             : 
      23             : // Local includes
      24             : #include "libmesh/libmesh_common.h"
      25             : #include "libmesh/reference_counted_object.h"
      26             : 
      27             : // C++ includes
      28             : #include <memory>
      29             : 
      30             : namespace libMesh
      31             : {
      32             : 
      33             : // Forward Declarations
      34             : class DiffContext;
      35             : class DiffSolver;
      36             : class DifferentiablePhysics;
      37             : class DifferentiableSystem;
      38             : class ParameterVector;
      39             : class SensitivityData;
      40             : class SolutionHistory;
      41             : class SystemNorm;
      42             : class QoISet;
      43             : class AdjointRefinementEstimator;
      44             : class ErrorVector;
      45             : 
      46             : template <typename T>
      47             : class LinearSolver;
      48             : 
      49             : /**
      50             :  * This is a generic class that defines a solver to handle
      51             :  * time integration of DifferentiableSystems.
      52             :  *
      53             :  * A user can define a solver by deriving from this class and
      54             :  * implementing certain functions.
      55             :  *
      56             :  * This class is part of the new DifferentiableSystem framework,
      57             :  * which is still experimental.  Users of this framework should
      58             :  * beware of bugs and future API changes.
      59             :  *
      60             :  * \author Roy H. Stogner
      61             :  * \date 2006
      62             :  */
      63         348 : class TimeSolver : public ReferenceCountedObject<TimeSolver>
      64             : {
      65             : public:
      66             :   /**
      67             :    * The type of system
      68             :    */
      69             :   typedef DifferentiableSystem sys_type;
      70             : 
      71             :   /**
      72             :    * Constructor. Requires a reference to the system
      73             :    * to be solved.
      74             :    */
      75             :   explicit
      76             :   TimeSolver (sys_type & s);
      77             : 
      78             :   /**
      79             :    * Destructor.
      80             :    */
      81             :   virtual ~TimeSolver ();
      82             : 
      83             :   /**
      84             :    * The initialization function.  This method is used to
      85             :    * initialize internal data structures before a simulation begins.
      86             :    */
      87             :   virtual void init ();
      88             : 
      89             :   /**
      90             :    * Initialize any adjoint related data structures, based on the number
      91             :    * of qois.
      92             :    */
      93             :   virtual void init_adjoints ();
      94             : 
      95             :   /**
      96             :    * The data initialization function.  This method is used to
      97             :    * initialize internal data structures after the underlying System
      98             :    * has been initialized
      99             :    */
     100             :   virtual void init_data ();
     101             : 
     102             :   /**
     103             :    * The reinitialization function.  This method is used after
     104             :    * changes in the mesh
     105             :    */
     106             :   virtual void reinit ();
     107             : 
     108             :   /**
     109             :    * This method solves for the solution at the next timestep (or
     110             :    * solves for a steady-state solution).  Usually we will only need
     111             :    * to solve one (non)linear system per timestep, but more complex
     112             :    * subclasses may override this.
     113             :    */
     114             :   virtual void solve ();
     115             : 
     116             :   /**
     117             :    * This method advances the solution to the next timestep, after a
     118             :    * solve() has been performed.  Often this will be done after every
     119             :    * UnsteadySolver::solve(), but adaptive mesh refinement and/or adaptive
     120             :    * time step selection may require some solve() steps to be repeated.
     121             :    */
     122             :   virtual void advance_timestep ();
     123             : 
     124             :   /**
     125             :    * This method solves for the adjoint solution at the next adjoint timestep
     126             :    * (or a steady state adjoint solve)
     127             :    */
     128             :   virtual std::pair<unsigned int, Real> adjoint_solve (const QoISet & qoi_indices);
     129             : 
     130             :   /**
     131             :    * This method advances the adjoint solution to the previous
     132             :    * timestep, after an adjoint_solve() has been performed.  This will
     133             :    * be done before every UnsteadySolver::adjoint_solve().
     134             :    */
     135             :   virtual void adjoint_advance_timestep ();
     136             : 
     137             :   /**
     138             :    * This method retrieves all the stored solutions at the current
     139             :    * system.time
     140             :    */
     141             :   virtual void retrieve_timestep();
     142             : 
     143             :   /**
     144             :    * A method to integrate the system::QoI functionals
     145             :    */
     146             :   virtual void integrate_qoi_timestep();
     147             : 
     148             :   /**
     149             :    * A method to integrate the adjoint sensitivity w.r.t a given parameter
     150             :    * vector. int_{tstep_start}^{tstep_end} dQ/dp dt = int_{tstep_start}^{tstep_end} (\partialQ / \partial p) - ( \partial R (u,z) / \partial p ) dt
     151             :    */
     152             :   virtual void integrate_adjoint_sensitivity(const QoISet & qois, const ParameterVector & parameter_vector, SensitivityData & sensitivities);
     153             : 
     154             : #ifdef LIBMESH_ENABLE_AMR
     155             :   /**
     156             :    * A method to compute the adjoint refinement error estimate at the current timestep.
     157             :    * int_{tstep_start}^{tstep_end} R(u^h,z) dt
     158             :    * The user provides an initialized ARefEE object.
     159             :    * Fills in an ErrorVector that contains the weighted sum of errors from all the QoIs and can be used to guide AMR.
     160             :    * CURRENTLY ONLY SUPPORTED for Backward Euler.
     161             :    */
     162             :   virtual void integrate_adjoint_refinement_error_estimate(AdjointRefinementEstimator & adjoint_refinement_error_estimator, ErrorVector & QoI_elementwise_error);
     163             : #endif // LIBMESH_ENABLE_AMR
     164             : 
     165             :   /**
     166             :    * This method uses the DifferentiablePhysics
     167             :    * element_time_derivative(), element_constraint(), and
     168             :    * mass_residual() to build a full residual on an element.  What
     169             :    * combination
     170             :    *
     171             :    * it uses will depend on the type of solver.  See
     172             :    * the subclasses for more details.
     173             :    */
     174             :   virtual bool element_residual (bool request_jacobian,
     175             :                                  DiffContext &) = 0;
     176             : 
     177             :   /**
     178             :    * This method uses the DifferentiablePhysics
     179             :    * side_time_derivative(), side_constraint(), and
     180             :    * side_mass_residual() to build a full residual on an element's
     181             :    * side.
     182             :    *
     183             :    * What combination it uses will depend on the type
     184             :    * of solver.  See the subclasses for more details.
     185             :    */
     186             :   virtual bool side_residual (bool request_jacobian,
     187             :                               DiffContext &) = 0;
     188             : 
     189             :   /**
     190             :    * This method uses the DifferentiablePhysics
     191             :    * nonlocal_time_derivative(), nonlocal_constraint(), and
     192             :    * nonlocal_mass_residual() to build a full residual of non-local
     193             :    * terms.
     194             :    *
     195             :    * What combination it uses will depend on the type
     196             :    * of solver.  See the subclasses for more details.
     197             :    */
     198             :   virtual bool nonlocal_residual (bool request_jacobian,
     199             :                                   DiffContext &) = 0;
     200             : 
     201             :   /**
     202             :    * This method is for subclasses or users to override
     203             :    * to do arbitrary processing between timesteps
     204             :    */
     205           0 :   virtual void before_timestep () {}
     206             : 
     207             :   /**
     208             :    * \returns A constant reference to the system we are solving.
     209             :    */
     210             :   const sys_type & system () const { return _system; }
     211             : 
     212             :   /**
     213             :    * \returns A writable reference to the system we are solving.
     214             :    */
     215    14725572 :   sys_type & system () { return _system; }
     216             : 
     217             :   /**
     218             :    * An implicit linear or nonlinear solver to use at each timestep.
     219             :    */
     220       60859 :   virtual std::unique_ptr<DiffSolver> & diff_solver() { return _diff_solver; }
     221             : 
     222             :   /**
     223             :    * An implicit linear solver to use for adjoint and sensitivity problems.
     224             :    */
     225      187333 :   virtual std::unique_ptr<LinearSolver<Number>> & linear_solver() { return _linear_solver; }
     226             : 
     227             :   /**
     228             :    * Print extra debugging information if quiet ==  false.
     229             :    */
     230             :   bool quiet;
     231             : 
     232             :   /**
     233             :    * Computes the size of ||u^{n+1} - u^{n}|| in some norm.
     234             :    *
     235             :    * \note While you can always call this function, its
     236             :    * result may or may not be very meaningful.  For example, if
     237             :    * you call this function right after calling advance_timestep()
     238             :    * then you'll get a result of zero since old_nonlinear_solution
     239             :    * is set equal to nonlinear_solution in this function.
     240             :    */
     241             :   virtual Real du(const SystemNorm & norm) const = 0;
     242             : 
     243             :   /**
     244             :    * Is this effectively a steady-state solver?
     245             :    */
     246             :   virtual bool is_steady() const = 0;
     247             : 
     248             :   /**
     249             :    * This value (which defaults to zero) is the number of times the
     250             :    * TimeSolver is allowed to halve deltat and let the DiffSolver
     251             :    * repeat the latest failed solve with a reduced timestep.
     252             :    *
     253             :    * \note This has no effect for SteadySolvers.
     254             :    * \note You must set at least one of the DiffSolver flags
     255             :    * "continue_after_max_iterations" or
     256             :    * "continue_after_backtrack_failure" to allow the TimeSolver to
     257             :    * retry the solve.
     258             :    */
     259             :   unsigned int reduce_deltat_on_diffsolver_failure;
     260             : 
     261             :   /**
     262             :    * A setter function users will employ if they need to do something
     263             :    * other than save no solution history
     264             :    */
     265             :   void set_solution_history(const SolutionHistory & _solution_history);
     266             : 
     267             :   /**
     268             :    * A getter function that returns a reference to the solution history
     269             :    * object owned by TimeSolver
     270             :    */
     271             :   SolutionHistory & get_solution_history();
     272             : 
     273             :   /**
     274             :    * Accessor for querying whether we need to do a primal
     275             :    * or adjoint solve
     276             :    */
     277       14404 :   bool is_adjoint() const
     278      269920 :   { return _is_adjoint; }
     279             : 
     280             :   /**
     281             :    * Accessor for setting whether we need to do a primal
     282             :    * or adjoint solve
     283             :    */
     284        1202 :   void set_is_adjoint(bool _is_adjoint_value)
     285       37816 :   { _is_adjoint = _is_adjoint_value; }
     286             : 
     287             :   /**
     288             :    * Returns system.deltat if fixed timestep solver is used,
     289             :    * the complete timestep size (sum of all substeps) if the adaptive
     290             :    * time solver is used.
     291             :    * Returns the change in system.time, deltat, for the last timestep which was successfully completed.
     292             :    * This only returns the outermost step size in the case of nested time solvers.
     293             :    * If no time step has yet been successfully completed, then returns system.deltat.
     294             :    */
     295             :   virtual Real last_completed_timestep_size();
     296             : 
     297             : protected:
     298             : 
     299             :   /**
     300             :    * An implicit linear or nonlinear solver to use at each timestep.
     301             :    */
     302             :   std::unique_ptr<DiffSolver> _diff_solver;
     303             : 
     304             :   /**
     305             :    * An implicit linear solver to use for adjoint problems.
     306             :    */
     307             :   std::unique_ptr<LinearSolver<Number>> _linear_solver;
     308             : 
     309             :   /**
     310             :    * A reference to the system we are solving.
     311             :    */
     312             :   sys_type & _system;
     313             : 
     314             :   /**
     315             :    * A std::unique_ptr to a SolutionHistory object. Default is
     316             :    * NoSolutionHistory, which the user can override by declaring a
     317             :    * different kind of SolutionHistory in the application
     318             :    */
     319             :   std::unique_ptr<SolutionHistory> solution_history;
     320             : 
     321             :   /**
     322             :    * Definitions of argument types for use in refactoring subclasses.
     323             :    */
     324             : 
     325             :   typedef bool (DifferentiablePhysics::*ResFuncType) (bool, DiffContext &);
     326             : 
     327             :   typedef void (DiffContext::*ReinitFuncType) (Real);
     328             : 
     329             :   /**
     330             :    * The deltat for the last completed timestep before the current one
     331             :    */
     332             :   Real last_deltat;
     333             : 
     334             : private:
     335             : 
     336             :   /**
     337             :    * This boolean tells the TimeSolver whether we are solving a primal or
     338             :    * adjoint problem
     339             :    */
     340             :   bool _is_adjoint;
     341             : 
     342             : };
     343             : 
     344             : 
     345             : } // namespace libMesh
     346             : 
     347             : 
     348             : #endif // LIBMESH_TIME_SOLVER_H

Generated by: LCOV version 1.14