Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
LinearSystem.C
Go to the documentation of this file.
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 #include "LinearSystem.h"
11 #include "AuxiliarySystem.h"
12 #include "Problem.h"
13 #include "FEProblem.h"
14 #include "PetscSupport.h"
15 #include "Factory.h"
16 #include "ParallelUniqueId.h"
21 #include "DisplacedProblem.h"
22 #include "Parser.h"
23 #include "MooseMesh.h"
24 #include "MooseUtils.h"
25 #include "MooseApp.h"
26 #include "TimeIntegrator.h"
27 #include "Assembly.h"
29 #include "Moose.h"
30 #include "ConsoleStream.h"
31 #include "MooseError.h"
32 #include "LinearFVKernel.h"
33 #include "UserObject.h"
34 #include "SolutionInvalidity.h"
35 #include "MooseLinearVariableFV.h"
36 #include "LinearFVTimeDerivative.h"
37 
38 // libMesh
39 #include "libmesh/linear_solver.h"
40 #include "libmesh/quadrature_gauss.h"
41 #include "libmesh/dense_vector.h"
42 #include "libmesh/boundary_info.h"
43 #include "libmesh/petsc_matrix.h"
44 #include "libmesh/petsc_vector.h"
45 #include "libmesh/petsc_nonlinear_solver.h"
46 #include "libmesh/numeric_vector.h"
47 #include "libmesh/mesh.h"
48 #include "libmesh/dense_subvector.h"
49 #include "libmesh/dense_submatrix.h"
50 #include "libmesh/dof_map.h"
51 #include "libmesh/sparse_matrix.h"
52 #include "libmesh/petsc_matrix.h"
53 #include "libmesh/default_coupling.h"
54 #include "libmesh/diagonal_matrix.h"
55 #include "libmesh/petsc_solver_exception.h"
56 
57 #include <ios>
58 
59 using namespace libMesh;
60 
61 namespace Moose
62 {
63 void
64 compute_linear_system(libMesh::EquationSystems & es, const std::string & system_name)
65 {
66  FEProblemBase * p = es.parameters.get<FEProblemBase *>("_fe_problem_base");
67  auto & sys = p->getLinearSystem(p->linearSysNum(system_name));
68  auto & lin_sys = sys.linearImplicitSystem();
69  auto & matrix = *(sys.linearImplicitSystem().matrix);
70  auto & rhs = *(sys.linearImplicitSystem().rhs);
71  p->computeLinearSystemSys(lin_sys, matrix, rhs);
72 }
73 }
74 
75 LinearSystem::LinearSystem(FEProblemBase & fe_problem, const std::string & name)
76  : SolverSystem(fe_problem, fe_problem, name, Moose::VAR_SOLVER),
77  PerfGraphInterface(fe_problem.getMooseApp().perfGraph(), "LinearSystem"),
78  _sys(fe_problem.es().add_system<LinearImplicitSystem>(name)),
79  _rhs_time_tag(-1),
80  _rhs_time(NULL),
81  _rhs_non_time_tag(-1),
82  _rhs_non_time(NULL),
83  _n_linear_iters(0),
84  _converged(false),
85  _linear_implicit_system(fe_problem.es().get_system<LinearImplicitSystem>(name))
86 {
88  // Don't need to add the matrix - it already exists (for now)
90 
91  // We create a tag for the right hand side, the vector is already in the libmesh system
93 
95 }
96 
97 LinearSystem::~LinearSystem() = default;
98 
99 void
101 {
103  // Checking if somebody accidentally assigned nonlinear variables to this system
104  const auto & var_names = _vars[0].names();
105  for (const auto & name : var_names)
106  if (!dynamic_cast<MooseLinearVariableFVReal *>(_vars[0].getVariable(name)))
107  mooseError("You are trying to add a nonlinear variable to a linear system! The variable "
108  "which is assigned to the wrong system: ",
109  name);
110 }
111 
112 void
113 LinearSystem::computeLinearSystemTags(const std::set<TagID> & vector_tags,
114  const std::set<TagID> & matrix_tags,
115  const bool compute_gradients)
116 {
117  parallel_object_only();
118 
119  TIME_SECTION("LinearSystem::computeLinearSystemTags", 5);
120 
122 
124 
125  try
126  {
127  computeLinearSystemInternal(vector_tags, matrix_tags, compute_gradients);
128  }
129  catch (MooseException & e)
130  {
131  // The buck stops here, we have already handled the exception by
132  // calling stopSolve(), it is now up to PETSc to return a
133  // "diverged" reason during the next solve.
134  }
135 }
136 
137 void
139 {
140  _new_gradient.clear();
141  for (auto & vec : _raw_grad_container)
142  _new_gradient.push_back(vec->zero_clone());
143 
144  TIME_SECTION("LinearVariableFV_Gradients", 3 /*, "Computing Linear FV variable gradients"*/);
145 
146  PARALLEL_TRY
147  {
149  FaceInfoRange face_info_range(_fe_problem.mesh().ownedFaceInfoBegin(),
151 
152  ComputeLinearFVGreenGaussGradientFaceThread gradient_face_thread(
154  Threads::parallel_reduce(face_info_range, gradient_face_thread);
155  }
156  PARALLEL_CATCH;
157 
158  for (auto & vec : _new_gradient)
159  vec->close();
160 
161  PARALLEL_TRY
162  {
164  ElemInfoRange elem_info_range(_fe_problem.mesh().ownedElemInfoBegin(),
166 
167  ComputeLinearFVGreenGaussGradientVolumeThread gradient_volume_thread(
169  Threads::parallel_reduce(elem_info_range, gradient_volume_thread);
170  }
171  PARALLEL_CATCH;
172 
173  for (const auto i : index_range(_raw_grad_container))
174  {
175  _new_gradient[i]->close();
176  _raw_grad_container[i] = std::move(_new_gradient[i]);
177  }
178 }
179 
180 void
181 LinearSystem::computeLinearSystemInternal(const std::set<TagID> & vector_tags,
182  const std::set<TagID> & matrix_tags,
183  const bool compute_gradients)
184 {
185  TIME_SECTION("computeLinearSystemInternal", 3);
186 
187  // Before we assemble we clear up the matrix and the vector
190 
191  // Make matrix ready to use
193 
194  for (auto tag : matrix_tags)
195  {
196  auto & matrix = getMatrix(tag);
197  // Necessary for speed
198  if (auto petsc_matrix = dynamic_cast<PetscMatrix<Number> *>(&matrix))
199  {
200  LibmeshPetscCall(MatSetOption(petsc_matrix->mat(),
201  MAT_KEEP_NONZERO_PATTERN, // This is changed in 3.1
202  PETSC_TRUE));
204  LibmeshPetscCall(
205  MatSetOption(petsc_matrix->mat(), MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
206  }
207  }
208 
209  if (compute_gradients)
211 
212  // linear contributions from the domain
213  PARALLEL_TRY
214  {
215  TIME_SECTION("LinearFVKernels_FullSystem", 3 /*, "Computing LinearFVKernels"*/);
216 
218  ElemInfoRange elem_info_range(_fe_problem.mesh().ownedElemInfoBegin(),
220 
222  FaceInfoRange face_info_range(_fe_problem.mesh().ownedFaceInfoBegin(),
224 
228  vector_tags);
229  Threads::parallel_reduce(elem_info_range, elem_thread);
230 
234  vector_tags);
235  Threads::parallel_reduce(face_info_range, face_thread);
236  }
237  PARALLEL_CATCH;
238 
239  closeTaggedMatrices(matrix_tags);
240 
243 
244  // Accumulate the occurrence of solution invalid warnings for the current iteration cumulative
245  // counters
248 }
249 
252 {
253  return *_rhs_time;
254 }
255 
258 {
259  return *_rhs_non_time;
260 }
261 
262 void
264  std::vector<dof_id_type> & /*n_nz*/,
265  std::vector<dof_id_type> & /*n_oz*/)
266 {
267  mooseError("LinearSystem does not support AugmentSparsity!");
268 }
269 
270 void
272 {
273  TIME_SECTION("LinearSystem::solve", 2, "Solving linear system");
274 
275  // Clear the iteration counters
276  _current_l_its = 0;
277 
278  system().solve();
279 
280  // store info about the solve
282 
283  auto & linear_solver =
284  libMesh::cast_ref<PetscLinearSolver<Real> &>(*_linear_implicit_system.get_linear_solver());
285  _initial_linear_residual = linear_solver.get_initial_residual();
287  _converged = linear_solver.get_converged_reason() > 0;
288 
289  _console << "System: " << this->name() << " Initial residual: " << _initial_linear_residual
290  << " Final residual: " << _final_linear_residual << " Num. of Iter. " << _n_linear_iters
291  << std::endl;
292 
293  // determine whether solution invalid occurs in the converged solution
295 }
296 
297 void
298 LinearSystem::stopSolve(const ExecFlagType & /*exec_flag*/,
299  const std::set<TagID> & vector_tags_to_close)
300 {
301  // We close the containers in case the solve restarts from a failed iteration
302  closeTaggedVectors(vector_tags_to_close);
304 }
305 
306 bool
308 {
309  // Right now, FV kernels are in TheWarehouse so we have to use that.
310  std::vector<LinearFVKernel *> kernels;
311  auto base_query = _fe_problem.theWarehouse()
312  .query()
313  .template condition<AttribSysNum>(this->number())
314  .template condition<AttribSystem>("LinearFVKernel")
315  .queryInto(kernels);
316 
317  bool contains_time_kernel = false;
318  for (const auto kernel : kernels)
319  {
320  contains_time_kernel = dynamic_cast<LinearFVTimeDerivative *>(kernel);
321  if (contains_time_kernel)
322  break;
323  }
324 
325  return contains_time_kernel;
326 }
327 
328 void
330 {
331  // Linear systems have their own time derivative computation machinery
332 }
std::string name(const ElemQuality q)
virtual void stopSolve(const ExecFlagType &exec_flag, const std::set< TagID > &vector_tags_to_close) override
Quit the current solve as soon as possible.
Definition: LinearSystem.C:298
The gradient in a volume using Green Gauss theorem and a cell-centered finite-volume approximation ca...
void computeGradients()
Compute the Green-Gauss gradients.
Definition: LinearSystem.C:138
unsigned int _n_linear_iters
Number of linear iterations.
Definition: LinearSystem.h:179
void checkInvalidSolution()
Definition: SolverSystem.C:111
face_info_iterator ownedFaceInfoBegin()
Iterators to owned faceInfo objects.
Definition: MooseMesh.C:1507
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
virtual bool containsTimeKernel() override
If the system has a kernel that corresponds to a time derivative.
Definition: LinearSystem.C:307
The gradient in a volume using Green Gauss theorem and a cell-centered finite-volume approximation ca...
NumericVector< Number > & getRightHandSideNonTimeVector()
Return a numeric vector that is associated with the nontime tag.
Definition: LinearSystem.C:257
virtual TagID addVectorTag(const TagName &tag_name, const Moose::VectorTagType type=Moose::VECTOR_TAG_RESIDUAL)
Create a Tag.
Definition: SubProblem.C:93
std::vector< T * > & queryInto(std::vector< T *> &results, Args &&... args)
queryInto executes the query and stores the results in the given vector.
Definition: TheWarehouse.h:311
void computeLinearSystemInternal(const std::set< TagID > &vector_tags, const std::set< TagID > &matrix_tags, const bool compute_gradients=true)
Compute the right hand side and system matrix for given tags.
Definition: LinearSystem.C:181
virtual void compute(ExecFlagType type) override
Compute time derivatives, auxiliary variables, etc.
Definition: LinearSystem.C:329
void compute_linear_system(libMesh::EquationSystems &es, const std::string &system_name)
Definition: LinearSystem.C:64
NumericVector< Number > * rhs
virtual LinearSolver< Number > * get_linear_solver() const override
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
unsigned int _current_l_its
The linear iterations needed for convergence.
Definition: LinearSystem.h:149
std::vector< std::unique_ptr< NumericVector< Number > > > _raw_grad_container
A cache for storing gradients at dof locations.
Definition: SystemBase.h:1065
Real _initial_linear_residual
The initial linear residual.
Definition: LinearSystem.h:182
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
std::vector< std::unique_ptr< NumericVector< Number > > > _new_gradient
Vectors to store the new gradients during the computation.
Definition: LinearSystem.h:197
Scope guard for starting and stopping Floating Point Exception Trapping.
virtual void zero()=0
elem_info_iterator ownedElemInfoBegin()
Iterators to owned faceInfo objects.
Definition: MooseMesh.C:1525
Adds contributions from volumetric terms discretized using the finite volume method to the matrix and...
virtual void initialSetup() override
Setup Functions.
Definition: LinearSystem.C:100
void computeLinearSystemSys(libMesh::LinearImplicitSystem &sys, libMesh::SparseMatrix< libMesh::Number > &system_matrix, NumericVector< libMesh::Number > &rhs, const bool compute_gradients=true)
Assemble both the right hand side and the system matrix of a given linear system. ...
virtual const std::string & name() const
Definition: SystemBase.C:1301
void closeTaggedMatrices(const std::set< TagID > &tags)
Close all matrices associated the tags.
Definition: SystemBase.C:1014
void solutionInvalidAccumulation()
Pass the number of solution invalid occurrences from current iteration to cumulative counters...
void syncIteration()
Sync iteration counts to main processor.
libMesh::LinearImplicitSystem & _linear_implicit_system
Base class reference to the linear implicit system in libmesh.
Definition: LinearSystem.h:191
NumericVector< Number > * _rhs_time
right hand side vector for time contributions
Definition: LinearSystem.h:161
const T & get(std::string_view) const
virtual void zero()=0
TheWarehouse & theWarehouse() const
unsigned int n_linear_iterations() const
Real _final_linear_residual
The final linear residual.
Definition: LinearSystem.h:185
SolutionInvalidity & solutionInvalidity()
Get the SolutionInvalidity for this app.
Definition: MooseApp.h:167
virtual TagID addMatrixTag(TagName tag_name)
Create a Tag.
Definition: SubProblem.C:312
TagID _rhs_tag
Used for the right hand side vector from PETSc.
Definition: LinearSystem.h:170
bool errorOnJacobianNonzeroReallocation() const
Will return True if the user wants to get an error when a nonzero is reallocated in the Jacobian by P...
virtual void activeAllMatrixTags()
Make all exsiting matrices ative.
Definition: SystemBase.C:1108
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1130
void attach_assemble_function(void fptr(EquationSystems &es, const std::string &name))
virtual void solve() override
Solve the system (using libMesh magic)
Definition: LinearSystem.C:271
void closeTaggedVectors(const std::set< TagID > &tags)
Close all vectors for given tags.
Definition: SystemBase.C:660
Interface for objects interacting with the PerfGraph.
virtual void solve()
virtual void close()=0
LinearSystem & getLinearSystem(unsigned int sys_num)
Get non-constant reference to a linear system.
Kernel that adds contributions from a time derivative term to a linear system populated using the fin...
TagID _system_matrix_tag
Tag for every contribution to system matrix.
Definition: LinearSystem.h:176
MooseApp & _app
Definition: SystemBase.h:982
FEProblemBase & _fe_problem
the governing finite element/volume problem
Definition: SystemBase.h:980
bool _converged
If the solve on the linear system converged.
Definition: LinearSystem.h:188
std::vector< VariableWarehouse > _vars
Variable warehouses (one for each thread)
Definition: SystemBase.h:990
Provides a way for users to bail out of the current solve.
NumericVector< Number > * _rhs_non_time
right hand side vector for non-time contributions
Definition: LinearSystem.h:167
virtual void close()=0
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
NumericVector< Number > & getRightHandSideTimeVector()
Return a numeric vector that is associated with the time tag.
Definition: LinearSystem.C:251
virtual libMesh::SparseMatrix< Number > & getMatrix(TagID tag)
Get a raw SparseMatrix.
Definition: SystemBase.C:978
SparseMatrix< Number > * matrix
void setCurrentLinearSystem(unsigned int sys_num)
Set the current linear system pointer.
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse...
Definition: TheWarehouse.h:466
virtual MooseMesh & mesh() override
unsigned int linearSysNum(const LinearSystemName &linear_sys_name) const override
virtual void augmentSparsity(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz) override
Will modify the sparsity pattern to add logical geometric connections.
Definition: LinearSystem.C:263
Adds contributions from face terms discretized using the finite volume method to the matrix and right...
elem_info_iterator ownedElemInfoEnd()
Definition: MooseMesh.C:1533
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
face_info_iterator ownedFaceInfoEnd()
Definition: MooseMesh.C:1516
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
Definition: SystemBase.C:89
virtual ~LinearSystem()
virtual void initialSetup()
Setup Functions.
Definition: SystemBase.C:1496
LinearSystem(FEProblemBase &problem, const std::string &name)
Definition: LinearSystem.C:75
auto index_range(const T &sizable)
virtual System & system() override
Get the reference to the libMesh system.
Definition: LinearSystem.h:107
void computeLinearSystemTags(const std::set< TagID > &vector_tags, const std::set< TagID > &matrix_tags, const bool compute_gradients=true)
Compute the right hand side and the system matrix of the system for given tags.
Definition: LinearSystem.C:113