LCOV - code coverage report
Current view: top level - include/systems - NonlinearSystemBase.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 65 66 98.5 %
Date: 2026-05-29 20:35:17 Functions: 44 45 97.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "SolverSystem.h"
      13             : #include "ConstraintWarehouse.h"
      14             : #include "MooseObjectWarehouse.h"
      15             : #include "MooseObjectTagWarehouse.h"
      16             : #include "PerfGraphInterface.h"
      17             : #include "ComputeMortarFunctor.h"
      18             : #include "MooseHashing.h"
      19             : 
      20             : #include "libmesh/transient_system.h"
      21             : #include "libmesh/nonlinear_implicit_system.h"
      22             : #include "libmesh/linear_solver.h"
      23             : 
      24             : // Forward declarations
      25             : class FEProblemBase;
      26             : class MoosePreconditioner;
      27             : class JacobianBlock;
      28             : class TimeIntegrator;
      29             : class Predictor;
      30             : class ElementDamper;
      31             : class NodalDamper;
      32             : class GeneralDamper;
      33             : class GeometricSearchData;
      34             : class IntegratedBCBase;
      35             : class NodalBCBase;
      36             : class DirichletBCBase;
      37             : class ADDirichletBCBase;
      38             : class DGKernelBase;
      39             : class InterfaceKernelBase;
      40             : class ScalarKernelBase;
      41             : class DiracKernelBase;
      42             : class NodalKernelBase;
      43             : class Split;
      44             : class KernelBase;
      45             : class HDGKernel;
      46             : class BoundaryCondition;
      47             : class ResidualObject;
      48             : class PenetrationInfo;
      49             : class FieldSplitPreconditionerBase;
      50             : 
      51             : // libMesh forward declarations
      52             : namespace libMesh
      53             : {
      54             : template <typename T>
      55             : class NumericVector;
      56             : template <typename T>
      57             : class SparseMatrix;
      58             : template <typename T>
      59             : class DiagonalMatrix;
      60             : class DofMapBase;
      61             : } // namespace libMesh
      62             : 
      63             : /**
      64             :  * Nonlinear system to be solved
      65             :  *
      66             :  * It is a part of FEProblemBase ;-)
      67             :  */
      68             : class NonlinearSystemBase : public SolverSystem, public PerfGraphInterface
      69             : {
      70             : public:
      71             :   NonlinearSystemBase(FEProblemBase & problem, libMesh::System & sys, const std::string & name);
      72             :   virtual ~NonlinearSystemBase();
      73             : 
      74             :   virtual void preInit() override;
      75             :   /// Update the mortar functors if the mesh has changed
      76             :   void reinitMortarFunctors();
      77             : 
      78             :   bool computedScalingJacobian() const { return _computed_scaling; }
      79             : 
      80             :   /**
      81             :    * Turn off the Jacobian (must be called before equation system initialization)
      82             :    */
      83             :   virtual void turnOffJacobian();
      84             : 
      85             :   virtual void solve() override = 0;
      86             : 
      87             :   virtual libMesh::NonlinearSolver<Number> * nonlinearSolver() = 0;
      88             : 
      89             :   virtual SNES getSNES() = 0;
      90             : 
      91             :   virtual unsigned int getCurrentNonlinearIterationNumber() = 0;
      92             : 
      93             :   /**
      94             :    * Returns true if this system is currently computing the pre-SMO residual for a solve.
      95             :    * @return Whether or not we are currently computing the pre-SMO residual.
      96             :    */
      97      761344 :   bool computingPreSMOResidual() { return _computing_pre_smo_residual; }
      98             : 
      99             :   // Setup Functions ////
     100             :   virtual void initialSetup() override;
     101             :   virtual void timestepSetup() override;
     102             :   virtual void customSetup(const ExecFlagType & exec_type) override;
     103             :   virtual void residualSetup() override;
     104             :   virtual void jacobianSetup() override;
     105             : 
     106             :   virtual void setupFiniteDifferencedPreconditioner() = 0;
     107             : 
     108             :   bool haveFiniteDifferencedPreconditioner() const
     109             :   {
     110             :     return _use_finite_differenced_preconditioner;
     111             :   }
     112             :   bool haveFieldSplitPreconditioner() const { return _fsp; }
     113             : 
     114             :   /**
     115             :    * Adds a kernel
     116             :    * @param kernel_name The type of the kernel
     117             :    * @param name The name of the kernel
     118             :    * @param parameters Kernel parameters
     119             :    */
     120             :   virtual void addKernel(const std::string & kernel_name,
     121             :                          const std::string & name,
     122             :                          InputParameters & parameters);
     123             : 
     124             :   /**
     125             :    * Adds a hybridized discontinuous Galerkin (HDG) kernel
     126             :    * @param kernel_name The type of the hybridized kernel
     127             :    * @param name The name of the hybridized kernel
     128             :    * @param parameters HDG kernel parameters
     129             :    */
     130             :   virtual void addHDGKernel(const std::string & kernel_name,
     131             :                             const std::string & name,
     132             :                             InputParameters & parameters);
     133             : 
     134             :   /**
     135             :    * Adds a NodalKernel
     136             :    * @param kernel_name The type of the nodal kernel
     137             :    * @param name The name of the kernel
     138             :    * @param parameters Kernel parameters
     139             :    */
     140             :   virtual void addNodalKernel(const std::string & kernel_name,
     141             :                               const std::string & name,
     142             :                               InputParameters & parameters);
     143             : 
     144             :   /**
     145             :    * Adds a scalar kernel
     146             :    * @param kernel_name The type of the kernel
     147             :    * @param name The name of the kernel
     148             :    * @param parameters Kernel parameters
     149             :    */
     150             :   void addScalarKernel(const std::string & kernel_name,
     151             :                        const std::string & name,
     152             :                        InputParameters & parameters);
     153             : 
     154             :   /**
     155             :    * Adds a boundary condition
     156             :    * @param bc_name The type of the boundary condition
     157             :    * @param name The name of the boundary condition
     158             :    * @param parameters Boundary condition parameters
     159             :    */
     160             :   void addBoundaryCondition(const std::string & bc_name,
     161             :                             const std::string & name,
     162             :                             InputParameters & parameters);
     163             : 
     164             : #ifdef MOOSE_KOKKOS_ENABLED
     165             :   /**
     166             :    * Adds a Kokkos kernel
     167             :    * @param kernel_name The type of the kernel
     168             :    * @param name The name of the kernel
     169             :    * @param parameters Kernel parameters
     170             :    */
     171             :   virtual void addKokkosKernel(const std::string & kernel_name,
     172             :                                const std::string & name,
     173             :                                InputParameters & parameters);
     174             : 
     175             :   /**
     176             :    * Adds a Kokkos nodal kernel
     177             :    * @param kernel_name The type of the nodal kernel
     178             :    * @param name The name of the kernel
     179             :    * @param parameters Kernel parameters
     180             :    */
     181             :   virtual void addKokkosNodalKernel(const std::string & kernel_name,
     182             :                                     const std::string & name,
     183             :                                     InputParameters & parameters);
     184             : 
     185             :   /**
     186             :    * Adds a Kokkos boundary condition
     187             :    * @param bc_name The type of the boundary condition
     188             :    * @param name The name of the boundary condition
     189             :    * @param parameters Boundary condition parameters
     190             :    */
     191             :   void addKokkosBoundaryCondition(const std::string & bc_name,
     192             :                                   const std::string & name,
     193             :                                   InputParameters & parameters);
     194             : #endif
     195             : 
     196             :   /**
     197             :    * Adds a Constraint
     198             :    * @param c_name The type of the constraint
     199             :    * @param name The name of the constraint
     200             :    * @param parameters Constraint parameters
     201             :    */
     202             :   void
     203             :   addConstraint(const std::string & c_name, const std::string & name, InputParameters & parameters);
     204             : 
     205             :   /**
     206             :    * Adds a Dirac kernel
     207             :    * @param kernel_name The type of the dirac kernel
     208             :    * @param name The name of the Dirac kernel
     209             :    * @param parameters Dirac kernel parameters
     210             :    */
     211             :   void addDiracKernel(const std::string & kernel_name,
     212             :                       const std::string & name,
     213             :                       InputParameters & parameters);
     214             : 
     215             :   /**
     216             :    * Adds a DG kernel
     217             :    * @param dg_kernel_name The type of the DG kernel
     218             :    * @param name The name of the DG kernel
     219             :    * @param parameters DG kernel parameters
     220             :    */
     221             :   void
     222             :   addDGKernel(std::string dg_kernel_name, const std::string & name, InputParameters & parameters);
     223             : 
     224             :   /**
     225             :    * Adds an interface kernel
     226             :    * @param interface_kernel_name The type of the interface kernel
     227             :    * @param name The name of the interface kernel
     228             :    * @param parameters interface kernel parameters
     229             :    */
     230             :   void addInterfaceKernel(std::string interface_kernel_name,
     231             :                           const std::string & name,
     232             :                           InputParameters & parameters);
     233             : 
     234             :   /**
     235             :    * Adds a damper
     236             :    * @param damper_name The type of the damper
     237             :    * @param name The name of the damper
     238             :    * @param parameters Damper parameters
     239             :    */
     240             :   void addDamper(const std::string & damper_name,
     241             :                  const std::string & name,
     242             :                  InputParameters & parameters);
     243             : 
     244             :   /**
     245             :    * Adds a split
     246             :    * @param split_name The type of the split
     247             :    * @param name The name of the split
     248             :    * @param parameters Split parameters
     249             :    */
     250             :   void
     251             :   addSplit(const std::string & split_name, const std::string & name, InputParameters & parameters);
     252             : 
     253             :   /**
     254             :    * Retrieves a split by name
     255             :    * @param name The name of the split
     256             :    */
     257             :   std::shared_ptr<Split> getSplit(const std::string & name);
     258             : 
     259             :   /**
     260             :    * Retrieves all splits
     261             :    */
     262       53935 :   MooseObjectWarehouseBase<Split> & getSplits() { return _splits; }
     263             : 
     264             :   /**
     265             :    * We offer the option to check convergence against the pre-SMO residual. This method handles the
     266             :    * logic as to whether we should perform such residual evaluation.
     267             :    *
     268             :    * @return A boolean indicating whether we should evaluate the pre-SMO residual.
     269             :    */
     270             :   bool shouldEvaluatePreSMOResidual() const;
     271             : 
     272             :   /**
     273             :    * Set whether to evaluate the pre-SMO residual and use it in the subsequent relative convergence
     274             :    * checks.
     275             :    *
     276             :    * If set to true, an _additional_ residual evaluation is performed before any
     277             :    * solution-modifying object is executed, and before the initial (0-th nonlinear iteration)
     278             :    * residual evaluation. Such residual is referred to as the pre-SMO residual. If the pre-SMO
     279             :    * residual is evaluated, it is used in the subsequent relative convergence checks.
     280             :    *
     281             :    * If set to false, no residual evaluation takes place before the initial residual evaluation, and
     282             :    * the initial residual is used in the subsequent relative convergence checks. This mode is
     283             :    * recommended for performance-critical code as it avoids the additional pre-SMO residual
     284             :    * evaluation.
     285             :    */
     286       58927 :   void setPreSMOResidual(bool use) { _use_pre_smo_residual = use; }
     287             : 
     288             :   /// Whether we are using pre-SMO residual in relative convergence checks
     289      403615 :   const bool & usePreSMOResidual() const { return _use_pre_smo_residual; }
     290             : 
     291             :   /// The reference residual used in relative convergence check.
     292             :   Real referenceResidual() const;
     293             : 
     294             :   /// The pre-SMO residual
     295             :   Real preSMOResidual() const;
     296             : 
     297             :   /// The initial residual
     298             :   Real initialResidual() const;
     299             : 
     300             :   /// Record the initial residual (for later relative convergence check)
     301             :   void setInitialResidual(Real r);
     302             : 
     303             :   void zeroVectorForResidual(const std::string & vector_name);
     304             : 
     305             :   void setInitialSolution();
     306             : 
     307             : #ifdef MOOSE_KOKKOS_ENABLED
     308             :   void setKokkosInitialSolution();
     309             : #endif
     310             : 
     311             :   /**
     312             :    * Sets the value of constrained variables in the solution vector.
     313             :    */
     314             :   void setConstraintSecondaryValues(NumericVector<Number> & solution, bool displaced);
     315             : 
     316             :   /**
     317             :    * Add residual contributions from Constraints
     318             :    *
     319             :    * @param residual - reference to the residual vector where constraint contributions will be
     320             :    * computed
     321             :    * @param displaced Controls whether to do the displaced Constraints or non-displaced
     322             :    */
     323             :   void constraintResiduals(NumericVector<Number> & residual, bool displaced);
     324             : 
     325             :   /**
     326             :    * Computes residual for a given tag
     327             :    * @param residual Residual is formed in here
     328             :    * @param the tag of kernels for which the residual is to be computed.
     329             :    */
     330             :   void computeResidualTag(NumericVector<Number> & residual, TagID tag_id);
     331             : 
     332             :   /**
     333             :    * Form multiple tag-associated residual vectors for all the given tags
     334             :    */
     335             :   void computeResidualTags(const std::set<TagID> & tags);
     336             : 
     337             :   /**
     338             :    * Form possibly multiple tag-associated vectors and matrices
     339             :    */
     340             :   void computeResidualAndJacobianTags(const std::set<TagID> & vector_tags,
     341             :                                       const std::set<TagID> & matrix_tags);
     342             : 
     343             :   /**
     344             :    * Compute residual and Jacobian from contributions not related to constraints, such as nodal
     345             :    * boundary conditions
     346             :    */
     347             :   void computeResidualAndJacobianInternal(const std::set<TagID> & vector_tags,
     348             :                                           const std::set<TagID> & matrix_tags);
     349             : 
     350             : #ifdef MOOSE_KOKKOS_ENABLED
     351             :   void computeKokkosResidualAndJacobian(const std::set<TagID> & vector_tags,
     352             :                                         const std::set<TagID> & matrix_tags);
     353             : #endif
     354             : 
     355             :   /**
     356             :    * Form a residual vector for a given tag
     357             :    */
     358             :   void computeResidual(NumericVector<Number> & residual, TagID tag_id);
     359             : 
     360             :   /**
     361             :    * Adds entries to the Jacobian in the correct positions for couplings coming from dofs being
     362             :    * coupled that
     363             :    * are related geometrically (i.e. near each other across a gap).
     364             :    */
     365             :   void addImplicitGeometricCouplingEntries(GeometricSearchData & geom_search_data);
     366             : 
     367             :   /**
     368             :    * Add jacobian contributions from Constraints
     369             :    *
     370             :    * @param jacobian reference to a read-only view of the Jacobian matrix
     371             :    * @param displaced Controls whether to do the displaced Constraints or non-displaced
     372             :    */
     373             :   void constraintJacobians(const SparseMatrix<Number> & jacobian_to_view, bool displaced);
     374             : 
     375             :   /**
     376             :    * Computes multiple (tag associated) Jacobian matricese
     377             :    */
     378             :   void computeJacobianTags(const std::set<TagID> & tags);
     379             : 
     380             :   /**
     381             :    * Method used to obtain scaling factors for variables
     382             :    * @returns whether this method ran without exceptions
     383             :    */
     384             :   bool computeScaling();
     385             : 
     386             :   /**
     387             :    * Associate jacobian to systemMatrixTag, and then form a matrix for all the tags
     388             :    */
     389             :   void computeJacobian(libMesh::SparseMatrix<Number> & jacobian, const std::set<TagID> & tags);
     390             : 
     391             :   /**
     392             :    * Take all tags in the system, and form a matrix for all tags in the system
     393             :    */
     394             :   void computeJacobian(libMesh::SparseMatrix<Number> & jacobian);
     395             : 
     396             :   /**
     397             :    * Computes several Jacobian blocks simultaneously, summing their contributions into smaller
     398             :    * preconditioning matrices.
     399             :    *
     400             :    * Used by Physics-based preconditioning
     401             :    *
     402             :    * @param blocks The blocks to fill in (JacobianBlock is defined in ComputeJacobianBlocksThread)
     403             :    */
     404             :   void computeJacobianBlocks(std::vector<JacobianBlock *> & blocks);
     405             : 
     406             :   void computeJacobianBlocks(std::vector<JacobianBlock *> & blocks, const std::set<TagID> & tags);
     407             : 
     408             :   /**
     409             :    * Compute damping
     410             :    * @param solution The trail solution vector
     411             :    * @param update The incremental update to the solution vector
     412             :    * @return returns The damping factor
     413             :    */
     414             :   Real computeDamping(const NumericVector<Number> & solution, const NumericVector<Number> & update);
     415             : 
     416             :   /**
     417             :    * Called at the beginning of the time step
     418             :    */
     419             :   void onTimestepBegin();
     420             : 
     421             :   using SystemBase::subdomainSetup;
     422             :   /**
     423             :    * Called from assembling when we hit a new subdomain
     424             :    * @param subdomain ID of the new subdomain
     425             :    * @param tid Thread ID
     426             :    */
     427             :   virtual void subdomainSetup(SubdomainID subdomain, THREAD_ID tid);
     428             : 
     429             :   /**
     430             :    * Called from explicit time stepping to overwrite boundary positions (explicit dynamics). This
     431             :    * will close/assemble the passed-in \p soln after overwrite
     432             :    */
     433             :   void overwriteNodeFace(NumericVector<Number> & soln);
     434             : 
     435             :   /**
     436             :    * Update active objects of Warehouses owned by NonlinearSystemBase
     437             :    */
     438             :   void updateActive(THREAD_ID tid);
     439             : 
     440             :   /**
     441             :    * Set transient term used by residual and Jacobian evaluation.
     442             :    * @param udot transient term
     443             :    * @note If the calling sequence for residual evaluation was changed, this could become an
     444             :    * explicit argument.
     445             :    */
     446             :   virtual void setSolutionUDot(const NumericVector<Number> & udot);
     447             : 
     448             :   /**
     449             :    * Set transient term used by residual and Jacobian evaluation.
     450             :    * @param udotdot transient term
     451             :    * @note If the calling sequence for residual evaluation was changed, this could become an
     452             :    * explicit argument.
     453             :    */
     454             :   virtual void setSolutionUDotDot(const NumericVector<Number> & udotdot);
     455             : 
     456             :   /**
     457             :    *  Return a numeric vector that is associated with the time tag.
     458             :    */
     459             :   NumericVector<Number> & getResidualTimeVector();
     460             : 
     461             :   /**
     462             :    * Return a numeric vector that is associated with the nontime tag.
     463             :    */
     464             :   NumericVector<Number> & getResidualNonTimeVector();
     465             : 
     466             :   /**
     467             :    * Return a residual vector that is associated with the residual tag.
     468             :    */
     469             :   NumericVector<Number> & residualVector(TagID tag);
     470             : 
     471             :   virtual NumericVector<Number> & residualCopy() override;
     472             :   virtual NumericVector<Number> & residualGhosted() override;
     473             : 
     474             :   virtual NumericVector<Number> & RHS() = 0;
     475             : 
     476             :   virtual void augmentSparsity(libMesh::SparsityPattern::Graph & sparsity,
     477             :                                std::vector<dof_id_type> & n_nz,
     478             :                                std::vector<dof_id_type> & n_oz) override;
     479             : 
     480             :   /**
     481             :    * Sets a preconditioner
     482             :    * @param pc The preconditioner to be set
     483             :    */
     484             :   void setPreconditioner(std::shared_ptr<MoosePreconditioner> pc);
     485             :   MoosePreconditioner const * getPreconditioner() const;
     486             : 
     487             :   /**
     488             :    * If called with true this system will use a finite differenced form of
     489             :    * the Jacobian as the preconditioner
     490             :    */
     491          86 :   void useFiniteDifferencedPreconditioner(bool use = true)
     492             :   {
     493          86 :     _use_finite_differenced_preconditioner = use;
     494          86 :   }
     495             : 
     496             :   /**
     497             :    * If called with a non-null object true this system will use a field split preconditioner matrix.
     498             :    */
     499         123 :   void useFieldSplitPreconditioner(FieldSplitPreconditionerBase * fsp) { _fsp = fsp; }
     500             : 
     501             :   /**
     502             :    * @returns A field split preconditioner. This will error if there is no field split
     503             :    * preconditioner
     504             :    */
     505             :   FieldSplitPreconditionerBase & getFieldSplitPreconditioner();
     506             : 
     507             :   /**
     508             :    * If called with true this will add entries into the jacobian to link together degrees of freedom
     509             :    * that are found to
     510             :    * be related through the geometric search system.
     511             :    *
     512             :    * These entries are really only used by the Finite Difference Preconditioner and the constraint
     513             :    * system right now.
     514             :    */
     515        1305 :   void addImplicitGeometricCouplingEntriesToJacobian(bool add = true)
     516             :   {
     517        1305 :     _add_implicit_geometric_coupling_entries_to_jacobian = add;
     518        1305 :   }
     519             : 
     520             :   /**
     521             :    * Indicates whether to assemble residual and Jacobian after each constraint application.
     522             :    * When true, enables "transitive" constraint application: subsequent constraints can use prior
     523             :    * constraints' results.
     524             :    */
     525             :   void assembleConstraintsSeparately(bool separately = true)
     526             :   {
     527             :     _assemble_constraints_separately = separately;
     528             :   }
     529             : 
     530             :   /**
     531             :    * Attach a customized preconditioner that requires physics knowledge.
     532             :    * Generic preconditioners should be implemented in PETSc, instead.
     533             :    */
     534             :   virtual void attachPreconditioner(libMesh::Preconditioner<Number> * preconditioner) = 0;
     535             : 
     536             :   /**
     537             :    * Setup damping stuff (called before we actually start)
     538             :    */
     539             :   void setupDampers();
     540             :   /**
     541             :    * Compute the incremental change in variables at QPs for dampers. Called before we use damping
     542             :    * @param tid Thread ID
     543             :    * @param damped_vars Set of variables for which increment is to be computed
     544             :    */
     545             :   void reinitIncrementAtQpsForDampers(THREAD_ID tid, const std::set<MooseVariable *> & damped_vars);
     546             : 
     547             :   /**
     548             :    * Compute the incremental change in variables at nodes for dampers. Called before we use damping
     549             :    * @param tid Thread ID
     550             :    * @param damped_vars Set of variables for which increment is to be computed
     551             :    */
     552             :   void reinitIncrementAtNodeForDampers(THREAD_ID tid,
     553             :                                        const std::set<MooseVariable *> & damped_vars);
     554             : 
     555             :   ///@{
     556             :   /// System Integrity Checks
     557             :   void checkKernelCoverage(const std::set<SubdomainID> & mesh_subdomains) const;
     558             :   virtual bool containsTimeKernel() override;
     559             :   virtual std::vector<std::string> timeKernelVariableNames() override;
     560             :   ///@}
     561             : 
     562             :   /**
     563             :    * Return the number of non-linear iterations
     564             :    */
     565        9797 :   virtual unsigned int nNonlinearIterations() const { return _n_iters; }
     566             : 
     567             :   /**
     568             :    * Return the number of linear iterations
     569             :    */
     570        8965 :   virtual unsigned int nLinearIterations() const { return _n_linear_iters; }
     571             : 
     572             :   /**
     573             :    * Return the total number of residual evaluations done so far in this calculation
     574             :    */
     575         152 :   unsigned int nResidualEvaluations() const { return _n_residual_evaluations; }
     576             : 
     577             :   /**
     578             :    * Return the final nonlinear residual
     579             :    */
     580         236 :   virtual Real finalNonlinearResidual() const { return _final_residual; }
     581             : 
     582             :   /**
     583             :    * Return the last nonlinear norm
     584             :    * @return A Real containing the last computed residual norm
     585             :    */
     586      435910 :   Real nonlinearNorm() const { return _last_nl_rnorm; }
     587             : 
     588             :   /**
     589             :    * Force the printing of all variable norms after each solve.
     590             :    * \todo{Remove after output update
     591             :    */
     592             :   void printAllVariableNorms(bool state) { _print_all_var_norms = state; }
     593             : 
     594          36 :   void debuggingResiduals(bool state) { _debugging_residuals = state; }
     595             : 
     596             :   unsigned int _num_residual_evaluations;
     597             : 
     598             :   void setPredictor(std::shared_ptr<Predictor> predictor);
     599          60 :   Predictor * getPredictor() { return _predictor.get(); }
     600             : 
     601             :   /**
     602             :    * Indicated whether this system needs material properties on boundaries.
     603             :    * @return Boolean if IntegratedBCs are active
     604             :    */
     605             :   bool needBoundaryMaterialOnSide(BoundaryID bnd_id, THREAD_ID tid) const;
     606             : 
     607             :   /**
     608             :    * Indicated whether this system needs material properties on interfaces.
     609             :    * @return Boolean if IntegratedBCs are active
     610             :    */
     611             :   bool needInterfaceMaterialOnSide(BoundaryID bnd_id, THREAD_ID tid) const;
     612             : 
     613             :   /**
     614             :    * Indicates whether this system needs material properties on internal sides.
     615             :    * @return Boolean if DGKernels are active
     616             :    */
     617             :   bool needInternalNeighborSideMaterial(SubdomainID subdomain_id, THREAD_ID tid) const;
     618             : 
     619             :   /**
     620             :    * Getter for _doing_dg
     621             :    */
     622             :   bool doingDG() const;
     623             : 
     624             :   //@{
     625             :   /**
     626             :    * Access functions to Warehouses from outside NonlinearSystemBase
     627             :    */
     628     3584861 :   MooseObjectTagWarehouse<KernelBase> & getKernelWarehouse() { return _kernels; }
     629          18 :   const MooseObjectTagWarehouse<KernelBase> & getKernelWarehouse() const { return _kernels; }
     630     3578713 :   MooseObjectTagWarehouse<DGKernelBase> & getDGKernelWarehouse() { return _dg_kernels; }
     631     3578693 :   MooseObjectTagWarehouse<InterfaceKernelBase> & getInterfaceKernelWarehouse()
     632             :   {
     633     3578693 :     return _interface_kernels;
     634             :   }
     635       35512 :   MooseObjectTagWarehouse<DiracKernelBase> & getDiracKernelWarehouse() { return _dirac_kernels; }
     636     5486275 :   MooseObjectTagWarehouse<IntegratedBCBase> & getIntegratedBCWarehouse() { return _integrated_bcs; }
     637          51 :   const MooseObjectTagWarehouse<ScalarKernelBase> & getScalarKernelWarehouse() const
     638             :   {
     639          51 :     return _scalar_kernels;
     640             :   }
     641          20 :   const MooseObjectTagWarehouse<NodalKernelBase> & getNodalKernelWarehouse() const
     642             :   {
     643          20 :     return _nodal_kernels;
     644             :   }
     645     3519717 :   MooseObjectTagWarehouse<HDGKernel> & getHDGKernelWarehouse() { return _hybridized_kernels; }
     646        1170 :   const MooseObjectWarehouse<ElementDamper> & getElementDamperWarehouse() const
     647             :   {
     648        1170 :     return _element_dampers;
     649             :   }
     650        1801 :   const MooseObjectWarehouse<NodalDamper> & getNodalDamperWarehouse() const
     651             :   {
     652        1801 :     return _nodal_dampers;
     653             :   }
     654             :   const ConstraintWarehouse & getConstraintWarehouse() const { return _constraints; }
     655             : 
     656             :   /**
     657             :    * Return the NodalBCBase warehouse
     658             :    */
     659     3053091 :   const MooseObjectTagWarehouse<NodalBCBase> & getNodalBCWarehouse() const { return _nodal_bcs; }
     660             : 
     661             :   /**
     662             :    * Return the IntegratedBCBase warehouse
     663             :    */
     664             :   const MooseObjectTagWarehouse<IntegratedBCBase> & getIntegratedBCWarehouse() const
     665             :   {
     666             :     return _integrated_bcs;
     667             :   }
     668             : 
     669             : #ifdef MOOSE_KOKKOS_ENABLED
     670             :   ///@{
     671             :   /// Return the Kokkos residual object warehouses
     672          19 :   MooseObjectTagWarehouse<ResidualObject> & getKokkosKernelWarehouse() { return _kokkos_kernels; }
     673           2 :   MooseObjectTagWarehouse<ResidualObject> & getKokkosNodalKernelWarehouse()
     674             :   {
     675           2 :     return _kokkos_nodal_kernels;
     676             :   }
     677        2265 :   MooseObjectTagWarehouse<ResidualObject> & getKokkosNodalBCWarehouse()
     678             :   {
     679        2265 :     return _kokkos_nodal_bcs;
     680             :   }
     681             :   MooseObjectTagWarehouse<ResidualObject> & getKokkosIntegratedBCWarehouse()
     682             :   {
     683             :     return _kokkos_integrated_bcs;
     684             :   }
     685             :   ///@}
     686             : #endif
     687             : 
     688             :   //@}
     689             : 
     690             :   /**
     691             :    * Weather or not the nonlinear system has save-ins
     692             :    */
     693     3036277 :   bool hasSaveIn() const { return _has_save_in || _has_nodalbc_save_in; }
     694             : 
     695             :   /**
     696             :    * Weather or not the nonlinear system has diagonal Jacobian save-ins
     697             :    */
     698      472515 :   bool hasDiagSaveIn() const { return _has_diag_save_in || _has_nodalbc_diag_save_in; }
     699             : 
     700   483326616 :   virtual libMesh::System & system() override { return _sys; }
     701   726751697 :   virtual const libMesh::System & system() const override { return _sys; }
     702             : 
     703             :   virtual void setSolutionUDotOld(const NumericVector<Number> & u_dot_old);
     704             : 
     705             :   virtual void setSolutionUDotDotOld(const NumericVector<Number> & u_dotdot_old);
     706             : 
     707             :   virtual void setPreviousNewtonSolution(const NumericVector<Number> & soln);
     708             : 
     709       91042 :   TagID timeVectorTag() const override { return _Re_time_tag; }
     710       64407 :   TagID nonTimeVectorTag() const override { return _Re_non_time_tag; }
     711    15140990 :   TagID residualVectorTag() const override { return _Re_tag; }
     712      985880 :   TagID systemMatrixTag() const override { return _Ke_system_tag; }
     713             : 
     714             :   /**
     715             :    * Call this method if you want the residual and Jacobian to be computed simultaneously
     716             :    */
     717             :   virtual void residualAndJacobianTogether() = 0;
     718             : 
     719             :   bool computeScalingOnce() const { return _compute_scaling_once; }
     720       58921 :   void computeScalingOnce(bool compute_scaling_once)
     721             :   {
     722       58921 :     _compute_scaling_once = compute_scaling_once;
     723       58921 :   }
     724             : 
     725             :   /**
     726             :    * Sets the param that indicates the weighting of the residual vs the Jacobian in determining
     727             :    * variable scaling parameters. A value of 1 indicates pure residual-based scaling. A value of 0
     728             :    * indicates pure Jacobian-based scaling
     729             :    */
     730       58921 :   void autoScalingParam(Real resid_vs_jac_scaling_param)
     731             :   {
     732       58921 :     _resid_vs_jac_scaling_param = resid_vs_jac_scaling_param;
     733       58921 :   }
     734             : 
     735          15 :   void scalingGroupVariables(const std::vector<std::vector<std::string>> & scaling_group_variables)
     736             :   {
     737          15 :     _scaling_group_variables = scaling_group_variables;
     738          15 :   }
     739             : 
     740             :   void
     741           9 :   ignoreVariablesForAutoscaling(const std::vector<std::string> & ignore_variables_for_autoscaling)
     742             :   {
     743           9 :     _ignore_variables_for_autoscaling = ignore_variables_for_autoscaling;
     744           9 :   }
     745             : 
     746       69804 :   bool offDiagonalsInAutoScaling() const { return _off_diagonals_in_auto_scaling; }
     747       58921 :   void offDiagonalsInAutoScaling(bool off_diagonals_in_auto_scaling)
     748             :   {
     749       58921 :     _off_diagonals_in_auto_scaling = off_diagonals_in_auto_scaling;
     750       58921 :   }
     751             : 
     752             :   libMesh::System & _sys;
     753             :   // FIXME: make these protected and create getters/setters
     754             :   Real _last_nl_rnorm;
     755             :   std::vector<unsigned int> _current_l_its;
     756             :   unsigned int _current_nl_its;
     757             : 
     758             :   /**
     759             :    * Setup the PETSc DM object (when appropriate)
     760             :    */
     761             :   void setupDM();
     762             : 
     763             :   using SystemBase::reinitNodeFace;
     764             : 
     765             :   /**
     766             :    * Create finite differencing contexts for assembly of the Jacobian and/or approximating the
     767             :    * action of the Jacobian on vectors (e.g. FD and/or MFFD respectively)
     768             :    */
     769           0 :   virtual void potentiallySetupFiniteDifferencing() {}
     770             : 
     771             :   /**
     772             :    * Destroy the coloring object if it exists
     773             :    */
     774             :   void destroyColoring();
     775             : 
     776             : protected:
     777             :   /**
     778             :    * Compute the residual for a given tag
     779             :    * @param tags The tags of kernels for which the residual is to be computed.
     780             :    */
     781             :   void computeResidualInternal(const std::set<TagID> & tags);
     782             : 
     783             : #ifdef MOOSE_KOKKOS_ENABLED
     784             :   /**
     785             :    * Compute residual with Kokkos objects
     786             :    */
     787             :   void computeKokkosResidual(const std::set<TagID> & tags);
     788             :   /**
     789             :    * Compute Kokkos nodal BCs
     790             :    */
     791             :   void computeKokkosNodalBCsResidual(const std::set<TagID> & tags);
     792             : #endif
     793             : 
     794             :   /**
     795             :    * Enforces nodal boundary conditions. The boundary condition will be implemented
     796             :    * in the residual using all the tags in the system.
     797             :    */
     798             :   void computeNodalBCsResidual(NumericVector<Number> & residual);
     799             : 
     800             :   /**
     801             :    * Form a residual for BCs that at least has one of the given tags.
     802             :    */
     803             :   void computeNodalBCsResidual(NumericVector<Number> & residual, const std::set<TagID> & tags);
     804             : 
     805             :   /**
     806             :    * Form multiple tag-associated residual vectors for the given tags.
     807             :    */
     808             :   void computeNodalBCsResidual(const std::set<TagID> & tags);
     809             : 
     810             :   /**
     811             :    * Compute the Jacobian for nodal boundary conditions
     812             :    */
     813             :   void computeNodalBCsJacobian(const std::set<TagID> & tags);
     814             : 
     815             :   /**
     816             :    * Compute the residual and Jacobian together for nodal boundary conditions
     817             :    */
     818             :   void computeNodalBCsResidualAndJacobian(const std::set<TagID> & vector_tags,
     819             :                                           const std::set<TagID> & matrix_tags);
     820             : 
     821             :   /**
     822             :    * Form multiple matrices for all the tags. Users should not call this func directly.
     823             :    */
     824             :   void computeJacobianInternal(const std::set<TagID> & tags);
     825             : 
     826             :   /**
     827             :    * Compute Jacobian with Kokkos objects
     828             :    */
     829             : #ifdef MOOSE_KOKKOS_ENABLED
     830             :   void computeKokkosJacobian(const std::set<TagID> & tags);
     831             : #endif
     832             : 
     833             :   void computeDiracContributions(const std::set<TagID> & tags, bool is_jacobian);
     834             : 
     835             :   void computeScalarKernelsJacobians(const std::set<TagID> & tags);
     836             : 
     837             :   /**
     838             :    * Enforce nodal constraints
     839             :    */
     840             :   void enforceNodalConstraintsResidual(NumericVector<Number> & residual);
     841             : 
     842             :   /**
     843             :    * Enforce nodal constraints in the Jacobian
     844             :    * @param jacobian The Jacobian to read from while constructing the Jacobians corresponding to the
     845             :    * nodal constraints
     846             :    * @returns Whether there were active nodal constraints
     847             :    */
     848             :   bool enforceNodalConstraintsJacobian(const SparseMatrix<Number> & jacobian);
     849             : 
     850             :   /**
     851             :    * Do mortar constraint residual/jacobian computations
     852             :    */
     853             :   void mortarConstraints(Moose::ComputeType compute_type,
     854             :                          const std::set<TagID> & vector_tags,
     855             :                          const std::set<TagID> & matrix_tags);
     856             : 
     857             :   /**
     858             :    * Compute a "Jacobian" for automatic scaling purposes
     859             :    */
     860             :   virtual void computeScalingJacobian() = 0;
     861             : 
     862             :   /**
     863             :    * Compute a "residual" for automatic scaling purposes
     864             :    */
     865             :   virtual void computeScalingResidual() = 0;
     866             : 
     867             :   /**
     868             :    * Assemble the numeric vector of scaling factors such that it can be used during assembly of the
     869             :    * system matrix
     870             :    */
     871             :   void assembleScalingVector();
     872             : 
     873             :   /**
     874             :    * Called after any ResidualObject-derived objects are added
     875             :    * to the system.
     876             :    */
     877      170191 :   virtual void postAddResidualObject(ResidualObject &) {}
     878             : 
     879             :   /**
     880             :    * Reinitialize quantities such as variables, residuals, Jacobians, materials for node-face
     881             :    * constraints
     882             :    */
     883             :   void reinitNodeFace(const Node & secondary_node,
     884             :                       const BoundaryID secondary_boundary,
     885             :                       const PenetrationInfo & info,
     886             :                       const bool displaced);
     887             : 
     888             :   /**
     889             :    * Perform some steps to get ready for the solver. These include
     890             :    * - zeroing iteration counters
     891             :    * - setting initial solutions
     892             :    * - possibly performing automatic scaling
     893             :    * - forming a scaling vector which, at least at some point, was required when AD objects were
     894             :    *   used with non-unity scaling factors for nonlinear variables
     895             :    * @returns Whether any exceptions were raised while running this method
     896             :    */
     897             :   bool preSolve();
     898             : 
     899             :   /// ghosted form of the residual
     900             :   NumericVector<Number> * _residual_ghosted;
     901             : 
     902             :   /// Copy of the residual vector, or nullptr if a copy is not needed
     903             :   std::unique_ptr<NumericVector<Number>> _residual_copy;
     904             : 
     905             :   /// \f$ {du^dot}\over{du} \f$
     906             :   Number _du_dot_du;
     907             :   /// \f$ {du^dotdot}\over{du} \f$
     908             :   Number _du_dotdot_du;
     909             : 
     910             :   /// Tag for time contribution residual
     911             :   TagID _Re_time_tag;
     912             : 
     913             :   /// Vector tags to temporarily store all tags associated with the current system.
     914             :   std::set<TagID> _nl_vector_tags;
     915             : 
     916             :   /// Matrix tags to temporarily store all tags associated with the current system.
     917             :   std::set<TagID> _nl_matrix_tags;
     918             : 
     919             :   /// residual vector for time contributions
     920             :   NumericVector<Number> * _Re_time;
     921             : 
     922             :   /// Tag for non-time contribution residual
     923             :   TagID _Re_non_time_tag;
     924             :   /// residual vector for non-time contributions
     925             :   NumericVector<Number> * _Re_non_time;
     926             : 
     927             :   /// Used for the residual vector from PETSc
     928             :   TagID _Re_tag;
     929             : 
     930             :   /// Tag for non-time contribution Jacobian
     931             :   TagID _Ke_non_time_tag;
     932             : 
     933             :   /// Tag for system contribution Jacobian
     934             :   TagID _Ke_system_tag;
     935             : 
     936             :   ///@{
     937             :   /// Kernel Storage
     938             :   MooseObjectTagWarehouse<KernelBase> _kernels;
     939             :   MooseObjectTagWarehouse<HDGKernel> _hybridized_kernels;
     940             :   MooseObjectTagWarehouse<ScalarKernelBase> _scalar_kernels;
     941             :   MooseObjectTagWarehouse<DGKernelBase> _dg_kernels;
     942             :   MooseObjectTagWarehouse<InterfaceKernelBase> _interface_kernels;
     943             :   ///@}
     944             : 
     945             :   ///@{
     946             :   /// BoundaryCondition Warhouses
     947             :   MooseObjectTagWarehouse<IntegratedBCBase> _integrated_bcs;
     948             :   MooseObjectTagWarehouse<NodalBCBase> _nodal_bcs;
     949             :   MooseObjectWarehouse<DirichletBCBase> _preset_nodal_bcs;
     950             :   MooseObjectWarehouse<ADDirichletBCBase> _ad_preset_nodal_bcs;
     951             :   ///@}
     952             : 
     953             : #ifdef MOOSE_KOKKOS_ENABLED
     954             :   ///@{
     955             :   /// Kokkos residual object warhouses
     956             :   MooseObjectTagWarehouse<ResidualObject> _kokkos_kernels;
     957             :   MooseObjectTagWarehouse<ResidualObject> _kokkos_integrated_bcs;
     958             :   MooseObjectTagWarehouse<ResidualObject> _kokkos_nodal_bcs;
     959             :   MooseObjectWarehouse<ResidualObject> _kokkos_preset_nodal_bcs;
     960             :   MooseObjectTagWarehouse<ResidualObject> _kokkos_nodal_kernels;
     961             :   ///@}
     962             : #endif
     963             : 
     964             :   /// Dirac Kernel storage for each thread
     965             :   MooseObjectTagWarehouse<DiracKernelBase> _dirac_kernels;
     966             : 
     967             :   /// Element Dampers for each thread
     968             :   MooseObjectWarehouse<ElementDamper> _element_dampers;
     969             : 
     970             :   /// Nodal Dampers for each thread
     971             :   MooseObjectWarehouse<NodalDamper> _nodal_dampers;
     972             : 
     973             :   /// General Dampers
     974             :   MooseObjectWarehouse<GeneralDamper> _general_dampers;
     975             : 
     976             :   /// NodalKernels for each thread
     977             :   MooseObjectTagWarehouse<NodalKernelBase> _nodal_kernels;
     978             : 
     979             :   /// Decomposition splits
     980             :   MooseObjectWarehouseBase<Split> _splits; // use base b/c there are no setup methods
     981             : 
     982             :   /// Constraints storage object
     983             :   ConstraintWarehouse _constraints;
     984             : 
     985             :   /// increment vector
     986             :   NumericVector<Number> * _increment_vec;
     987             :   /// Preconditioner
     988             :   std::shared_ptr<MoosePreconditioner> _preconditioner;
     989             : 
     990             :   /// Whether or not to use a finite differenced preconditioner
     991             :   bool _use_finite_differenced_preconditioner;
     992             : 
     993             :   MatFDColoring _fdcoloring;
     994             : 
     995             :   /// The field split preconditioner if this sytem is using one
     996             :   FieldSplitPreconditionerBase * _fsp;
     997             : 
     998             :   /// Whether or not to add implicit geometric couplings to the Jacobian for FDP
     999             :   bool _add_implicit_geometric_coupling_entries_to_jacobian;
    1000             : 
    1001             :   /// Whether or not to assemble the residual and Jacobian after the application of each constraint.
    1002             :   bool _assemble_constraints_separately;
    1003             : 
    1004             :   /// Whether or not a ghosted copy of the residual needs to be made
    1005             :   bool _need_residual_ghosted;
    1006             :   /// true if debugging residuals
    1007             :   bool _debugging_residuals;
    1008             : 
    1009             :   /// true if DG is active (optimization reasons)
    1010             :   bool _doing_dg;
    1011             : 
    1012             :   /// vectors that will be zeroed before a residual computation
    1013             :   std::vector<std::string> _vecs_to_zero_for_residual;
    1014             : 
    1015             :   unsigned int _n_iters;
    1016             :   unsigned int _n_linear_iters;
    1017             : 
    1018             :   /// Total number of residual evaluations that have been performed
    1019             :   unsigned int _n_residual_evaluations;
    1020             : 
    1021             :   Real _final_residual;
    1022             : 
    1023             :   /// If predictor is active, this is non-NULL
    1024             :   std::shared_ptr<Predictor> _predictor;
    1025             : 
    1026             :   bool _computing_pre_smo_residual;
    1027             : 
    1028             :   /// The pre-SMO residual, see setPreSMOResidual for a detailed explanation
    1029             :   Real _pre_smo_residual;
    1030             :   /// The initial (i.e., 0th nonlinear iteration) residual, see setPreSMOResidual for a detailed explanation
    1031             :   Real _initial_residual;
    1032             :   /// Whether to use the pre-SMO initial residual in the relative convergence check
    1033             :   bool _use_pre_smo_residual;
    1034             : 
    1035             :   bool _print_all_var_norms;
    1036             : 
    1037             :   /// If there is any Kernel or IntegratedBC having save_in
    1038             :   bool _has_save_in;
    1039             : 
    1040             :   /// If there is any Kernel or IntegratedBC having diag_save_in
    1041             :   bool _has_diag_save_in;
    1042             : 
    1043             :   /// If there is a nodal BC having save_in
    1044             :   bool _has_nodalbc_save_in;
    1045             : 
    1046             :   /// If there is a nodal BC having diag_save_in
    1047             :   bool _has_nodalbc_diag_save_in;
    1048             : 
    1049             :   void getNodeDofs(dof_id_type node_id, std::vector<dof_id_type> & dofs);
    1050             : 
    1051             :   /// Flag used to indicate whether we have already computed the scaling Jacobian
    1052             :   bool _computed_scaling;
    1053             : 
    1054             :   /// Whether the scaling factors should only be computed once at the beginning of the simulation
    1055             :   /// through an extra Jacobian evaluation. If this is set to false, then the scaling factors will
    1056             :   /// be computed during an extra Jacobian evaluation at the beginning of every time step.
    1057             :   bool _compute_scaling_once;
    1058             : 
    1059             :   /// The param that indicates the weighting of the residual vs the Jacobian in determining
    1060             :   /// variable scaling parameters. A value of 1 indicates pure residual-based scaling. A value of 0
    1061             :   /// indicates pure Jacobian-based scaling
    1062             :   Real _resid_vs_jac_scaling_param;
    1063             : 
    1064             :   /// A container of variable groupings that can be used in scaling calculations. This can be useful
    1065             :   /// for simulations in which vector-like variables are split into invidual scalar-field components
    1066             :   /// like for solid/fluid mechanics
    1067             :   std::vector<std::vector<std::string>> _scaling_group_variables;
    1068             : 
    1069             :   /// Container to hold flag if variable is to participate in autoscaling
    1070             :   std::vector<bool> _variable_autoscaled;
    1071             : 
    1072             :   /// A container for variables that do not partipate in autoscaling
    1073             :   std::vector<std::string> _ignore_variables_for_autoscaling;
    1074             : 
    1075             :   /// Whether to include off diagonals when determining automatic scaling factors
    1076             :   bool _off_diagonals_in_auto_scaling;
    1077             : 
    1078             :   /// A diagonal matrix used for computing scaling
    1079             :   std::unique_ptr<libMesh::DiagonalMatrix<Number>> _scaling_matrix;
    1080             : 
    1081             : private:
    1082             :   /**
    1083             :    * Finds the implicit sparsity graph between geometrically related dofs.
    1084             :    */
    1085             :   void findImplicitGeometricCouplingEntries(
    1086             :       GeometricSearchData & geom_search_data,
    1087             :       std::unordered_map<dof_id_type, std::vector<dof_id_type>> & graph);
    1088             : 
    1089             :   /**
    1090             :    * Setup group scaling containers
    1091             :    */
    1092             :   void setupScalingData();
    1093             : 
    1094             :   /// Functors for computing undisplaced mortar constraints
    1095             :   std::unordered_map<std::pair<BoundaryID, BoundaryID>, ComputeMortarFunctor>
    1096             :       _undisplaced_mortar_functors;
    1097             : 
    1098             :   /// Functors for computing displaced mortar constraints
    1099             :   std::unordered_map<std::pair<BoundaryID, BoundaryID>, ComputeMortarFunctor>
    1100             :       _displaced_mortar_functors;
    1101             : 
    1102             :   /// The current states of the solution (0 = current, 1 = old, etc)
    1103             :   std::vector<NumericVector<Number> *> _solution_state;
    1104             : 
    1105             :   /// Whether we've initialized the automatic scaling data structures
    1106             :   bool _auto_scaling_initd;
    1107             : 
    1108             :   /// A map from variable index to group variable index and it's associated (inverse) scaling factor
    1109             :   std::unordered_map<unsigned int, unsigned int> _var_to_group_var;
    1110             : 
    1111             :   /// The number of scaling groups
    1112             :   std::size_t _num_scaling_groups;
    1113             : };

Generated by: LCOV version 1.14