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 "NonlinearSystemBase.h" 13 : #include "ComputeResidualFunctor.h" 14 : #include "ComputeFDResidualFunctor.h" 15 : #include "ComputeResidualAndJacobian.h" 16 : #include "SubProblem.h" 17 : #include "MooseError.h" 18 : 19 : #include "libmesh/transient_system.h" 20 : #include "libmesh/nonlinear_implicit_system.h" 21 : 22 : /** 23 : * Nonlinear system to be solved 24 : * 25 : * It is a part of FEProblemBase ;-) 26 : */ 27 : class NonlinearSystem : public NonlinearSystemBase 28 : { 29 : public: 30 : NonlinearSystem(FEProblemBase & problem, const std::string & name); 31 : virtual ~NonlinearSystem(); 32 : 33 : virtual void solve() override; 34 : 35 : /** 36 : * Quit the current solve as soon as possible. 37 : */ 38 : virtual void stopSolve(const ExecFlagType & exec_flag, 39 : const std::set<TagID> & vector_tags_to_close) override; 40 : 41 : /** 42 : * Returns the current nonlinear iteration number. In libmesh, this is 43 : * updated during the nonlinear solve, so it should be up-to-date. 44 : */ 45 2507459 : virtual unsigned int getCurrentNonlinearIterationNumber() override 46 : { 47 2507459 : return _nl_implicit_sys.get_current_nonlinear_iteration_number(); 48 : } 49 : 50 : virtual void setupFiniteDifferencedPreconditioner() override; 51 : 52 : /** 53 : * Returns the convergence state 54 : * @return true if converged, otherwise false 55 : */ 56 : virtual bool converged() override; 57 : 58 447272 : virtual NumericVector<Number> & RHS() override { return *_nl_implicit_sys.rhs; } 59 : 60 1765293 : virtual libMesh::NonlinearSolver<Number> * nonlinearSolver() override 61 : { 62 1765293 : return _nl_implicit_sys.nonlinear_solver.get(); 63 : } 64 : 65 : virtual SNES getSNES() override; 66 : 67 54794 : virtual libMesh::NonlinearImplicitSystem & sys() { return _nl_implicit_sys; } 68 : 69 : virtual void attachPreconditioner(libMesh::Preconditioner<Number> * preconditioner) override; 70 : 71 : virtual void residualAndJacobianTogether() override; 72 : 73 : virtual void potentiallySetupFiniteDifferencing() override; 74 : 75 : protected: 76 : void computeScalingJacobian() override; 77 : void computeScalingResidual() override; 78 : 79 : libMesh::NonlinearImplicitSystem & _nl_implicit_sys; 80 : ComputeResidualFunctor _nl_residual_functor; 81 : ComputeFDResidualFunctor _fd_residual_functor; 82 : ComputeResidualAndJacobian _resid_and_jac_functor; 83 : 84 : private: 85 : /** 86 : * Form preconditioning matrix via a standard finite difference method 87 : * column-by-column. This method computes both diagonal and off-diagonal 88 : * entrices regardless of the structure pattern of the Jacobian matrix. 89 : */ 90 : void setupStandardFiniteDifferencedPreconditioner(); 91 : 92 : /** 93 : * According to the nonzero pattern provided in the matrix, a graph is constructed. 94 : * A coloring algorithm is applied to the graph. The graph is partitioned into several 95 : * independent subgraphs (colors), and a finte difference method is applied color-by-color 96 : * to form a preconditioning matrix. If the number of colors is small, this method is much 97 : * faster than the standard FD. But there is an issue. If the matrix provided by users does not 98 : * represent the actual structure of the true Jacobian, the matrix computed via coloring could 99 : * be wrong or inaccurate. In this case, users should switch to the standard finite difference 100 : * method. 101 : */ 102 : void setupColoringFiniteDifferencedPreconditioner(); 103 : 104 492708 : virtual bool matrixFromColoring() const override { return _use_coloring_finite_difference; } 105 : 106 : bool _use_coloring_finite_difference; 107 : };