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 "PerfGraphInterface.h" 14 : 15 : #include "libmesh/transient_system.h" 16 : #include "libmesh/linear_implicit_system.h" 17 : #include "libmesh/linear_solver.h" 18 : 19 : class LinearFVKernel; 20 : 21 : // libMesh forward declarations 22 : namespace libMesh 23 : { 24 : template <typename T> 25 : class NumericVector; 26 : template <typename T> 27 : class SparseMatrix; 28 : template <typename T> 29 : class DiagonalMatrix; 30 : } // namespace libMesh 31 : 32 : /** 33 : * Linear system to be solved 34 : */ 35 : class LinearSystem : public SolverSystem, public PerfGraphInterface 36 : { 37 : public: 38 : LinearSystem(FEProblemBase & problem, const std::string & name); 39 : virtual ~LinearSystem(); 40 : 41 : virtual void solve() override; 42 : 43 : /** 44 : * At the moment, this is only used for the multi-system fixed point 45 : * iteration. We return true here since ther is no way to specify 46 : * separate linear residuals in FEProblemSolve yet. 47 : */ 48 4897 : virtual bool converged() override { return _converged; } 49 : 50 : virtual void initialSetup() override; 51 : 52 : // Overriding these to make sure the linear systems don't do anything during 53 : // residual/jacobian setup 54 0 : virtual void residualSetup() override {} 55 0 : virtual void jacobianSetup() override {} 56 : 57 : /** 58 : * Quit the current solve as soon as possible. 59 : */ 60 : virtual void stopSolve(const ExecFlagType & exec_flag, 61 : const std::set<TagID> & vector_tags_to_close) override; 62 : 63 : /** 64 : * If the system has a kernel that corresponds to a time derivative. 65 : * Considering that we don't have transient capabilities for linear 66 : * systems at the moment, this is false. 67 : */ 68 : virtual bool containsTimeKernel() override; 69 0 : virtual std::vector<std::string> timeKernelVariableNames() override { return {}; } 70 : 71 : /** 72 : * Compute the right hand side and the system matrix of the system for given tags. 73 : * @param vector_tags The IDs of the vector tags whose right hand side contribution should be 74 : * included 75 : * @param matrix_tags The IDs of the matrix tags whose matrix contribution should be included 76 : * @param compute_gradients A flag to disable the computation of new gradients during the 77 : * assembly, can be used to lag gradients 78 : */ 79 : void computeLinearSystemTags(const std::set<TagID> & vector_tags, 80 : const std::set<TagID> & matrix_tags, 81 : const bool compute_gradients = true); 82 : 83 : /** 84 : * Return a reference to the stored linear implicit system 85 : */ 86 21110 : libMesh::LinearImplicitSystem & linearImplicitSystem() { return _linear_implicit_system; } 87 : 88 : /** 89 : * Return a numeric vector that is associated with the time tag. 90 : */ 91 : NumericVector<Number> & getRightHandSideTimeVector(); 92 : 93 : /** 94 : * Return a numeric vector that is associated with the nontime tag. 95 : */ 96 : NumericVector<Number> & getRightHandSideNonTimeVector(); 97 : 98 : virtual void augmentSparsity(SparsityPattern::Graph & sparsity, 99 : std::vector<dof_id_type> & n_nz, 100 : std::vector<dof_id_type> & n_oz) override; 101 : 102 : /** 103 : * Return the number of linear iterations 104 : */ 105 176 : unsigned int nLinearIterations() const { return _n_linear_iters; } 106 : 107 71347 : virtual System & system() override { return _sys; } 108 2089583 : virtual const System & system() const override { return _sys; } 109 : 110 : ///@{ 111 : /// Accessors of important tag IDs 112 0 : TagID rightHandSideTimeVectorTag() const { return _rhs_time_tag; } 113 : TagID rightHandSideNonTimeVectorTag() const { return _rhs_non_time_tag; } 114 14871 : TagID rightHandSideVectorTag() const { return _rhs_tag; } 115 14871 : virtual TagID systemMatrixTag() const override { return _system_matrix_tag; } 116 : ///@} 117 : 118 : /// Fetching the right hand side vector from the libmesh system. 119 4957 : NumericVector<Number> & getRightHandSideVector() { return *_linear_implicit_system.rhs; } 120 : const NumericVector<Number> & getRightHandSideVector() const 121 : { 122 : return *_linear_implicit_system.rhs; 123 : } 124 : 125 : /// Fetching the system matrix from the libmesh system. 126 4957 : SparseMatrix<Number> & getSystemMatrix() { return *_linear_implicit_system.matrix; } 127 : const SparseMatrix<Number> & getSystemMatrix() const { return *_linear_implicit_system.matrix; } 128 : 129 : /** 130 : * Compute the Green-Gauss gradients 131 : */ 132 : void computeGradients(); 133 : 134 : /** 135 : * Return a reference to the new (temporary) gradient container vectors 136 : */ 137 19730 : std::vector<std::unique_ptr<NumericVector<Number>>> & newGradientContainer() 138 : { 139 19730 : return _new_gradient; 140 : } 141 : 142 : virtual void compute(ExecFlagType type) override; 143 : 144 : protected: 145 : /** 146 : * Compute the right hand side and system matrix for given tags 147 : * @param vector_tags The tags of kernels for which the right hand side is to be computed. 148 : * @param matrix_tags The tags of kernels for which the system matrix is to be computed. 149 : * @param compute_gradients A flag to disable the computation of new gradients during the 150 : * assembly, can be used to lag gradients 151 : */ 152 : void computeLinearSystemInternal(const std::set<TagID> & vector_tags, 153 : const std::set<TagID> & matrix_tags, 154 : const bool compute_gradients = true); 155 : 156 : /// Base class reference to the libmesh system 157 : System & _sys; 158 : 159 : /// The linear iterations needed for convergence 160 : unsigned int _current_l_its; 161 : 162 : /// Vector tags to temporarily store all tags associated with the current system. 163 : std::set<TagID> _vector_tags; 164 : 165 : /// Matrix tags to temporarily store all tags associated with the current system. 166 : std::set<TagID> _matrix_tags; 167 : 168 : /// Tag for time contribution rhs 169 : TagID _rhs_time_tag; 170 : 171 : /// right hand side vector for time contributions 172 : NumericVector<Number> * _rhs_time; 173 : 174 : /// Tag for non-time contribution rhs 175 : TagID _rhs_non_time_tag; 176 : 177 : /// right hand side vector for non-time contributions 178 : NumericVector<Number> * _rhs_non_time; 179 : 180 : /// Used for the right hand side vector from PETSc 181 : TagID _rhs_tag; 182 : 183 : /// Tag for non-time contribution to the system matrix 184 : TagID _system_matrix_non_time_tag; 185 : 186 : /// Tag for every contribution to system matrix 187 : TagID _system_matrix_tag; 188 : 189 : /// Number of linear iterations 190 : unsigned int _n_linear_iters; 191 : 192 : /// The initial linear residual 193 : Real _initial_linear_residual; 194 : 195 : /// The final linear residual 196 : Real _final_linear_residual; 197 : 198 : /// If the solve on the linear system converged 199 : bool _converged; 200 : 201 : /// Base class reference to the linear implicit system in libmesh 202 : libMesh::LinearImplicitSystem & _linear_implicit_system; 203 : 204 : /// Vectors to store the new gradients during the computation. This is needed 205 : /// because the old gradients might still be needed to determine boundary values 206 : /// (for extrapolated boundary conditions). Once the computation is done, we 207 : /// move the nev vectors to the original containers. 208 : std::vector<std::unique_ptr<NumericVector<Number>>> _new_gradient; 209 : 210 : private: 211 : /// The current states of the solution (0 = current, 1 = old, etc) 212 : std::vector<NumericVector<Number> *> _solution_state; 213 : };