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 : #include "SolverSystem.h" 11 : #include "SolutionInvalidity.h" 12 : #include "FEProblemBase.h" 13 : #include "TimeIntegrator.h" 14 : 15 : using namespace libMesh; 16 : 17 58214 : SolverSystem::SolverSystem(SubProblem & subproblem, 18 : FEProblemBase & fe_problem, 19 : const std::string & name, 20 58214 : Moose::VarKindType var_kind) 21 : : SystemBase(subproblem, fe_problem, name, var_kind), 22 58214 : _current_solution(nullptr), 23 58214 : _pc_side(Moose::PCS_DEFAULT), 24 58214 : _ksp_norm(Moose::KSPN_UNPRECONDITIONED), 25 58214 : _solution_is_invalid(false) 26 : { 27 58214 : } 28 : 29 53921 : SolverSystem::~SolverSystem() = default; 30 : 31 : void 32 56324 : SolverSystem::preInit() 33 : { 34 56324 : SystemBase::preInit(); 35 : 36 56324 : _current_solution = system().current_local_solution.get(); 37 : 38 56324 : if (_serialized_solution.get()) 39 36 : _serialized_solution->init(system().n_dofs(), false, SERIAL); 40 56324 : } 41 : 42 : void 43 4214 : SolverSystem::restoreSolutions() 44 : { 45 : // call parent 46 4214 : SystemBase::restoreSolutions(); 47 : // and update _current_solution 48 4214 : _current_solution = system().current_local_solution.get(); 49 4214 : } 50 : 51 : void 52 3729 : SolverSystem::serializeSolution() 53 : { 54 3729 : if (_serialized_solution.get()) 55 : { 56 3729 : if (!_serialized_solution->initialized() || _serialized_solution->size() != system().n_dofs()) 57 : { 58 58 : _serialized_solution->clear(); 59 58 : _serialized_solution->init(system().n_dofs(), false, SERIAL); 60 : } 61 : 62 3729 : _current_solution->localize(*_serialized_solution); 63 : } 64 3729 : } 65 : 66 : void 67 3595372 : SolverSystem::setSolution(const NumericVector<Number> & soln) 68 : { 69 3595372 : _current_solution = &soln; 70 : 71 3595372 : auto tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG); 72 3595372 : associateVectorToTag(const_cast<NumericVector<Number> &>(soln), tag); 73 : 74 3595372 : if (_serialized_solution.get()) 75 3729 : serializeSolution(); 76 3595372 : } 77 : 78 : void 79 13492 : SolverSystem::setPCSide(MooseEnum pcs) 80 : { 81 13492 : if (pcs == "left") 82 0 : _pc_side = Moose::PCS_LEFT; 83 13492 : else if (pcs == "right") 84 0 : _pc_side = Moose::PCS_RIGHT; 85 13492 : else if (pcs == "symmetric") 86 0 : _pc_side = Moose::PCS_SYMMETRIC; 87 13492 : else if (pcs == "default") 88 13492 : _pc_side = Moose::PCS_DEFAULT; 89 : else 90 0 : mooseError("Unknown PC side specified."); 91 13492 : } 92 : 93 : void 94 13492 : SolverSystem::setMooseKSPNormType(MooseEnum kspnorm) 95 : { 96 13492 : if (kspnorm == "none") 97 0 : _ksp_norm = Moose::KSPN_NONE; 98 13492 : else if (kspnorm == "preconditioned") 99 0 : _ksp_norm = Moose::KSPN_PRECONDITIONED; 100 13492 : else if (kspnorm == "unpreconditioned") 101 13492 : _ksp_norm = Moose::KSPN_UNPRECONDITIONED; 102 0 : else if (kspnorm == "natural") 103 0 : _ksp_norm = Moose::KSPN_NATURAL; 104 0 : else if (kspnorm == "default") 105 0 : _ksp_norm = Moose::KSPN_DEFAULT; 106 : else 107 0 : mooseError("Unknown ksp norm type specified."); 108 13492 : } 109 : 110 : void 111 290059 : SolverSystem::checkInvalidSolution() 112 : { 113 290059 : auto & solution_invalidity = _app.solutionInvalidity(); 114 : 115 : // sync all solution invalid counts to rank 0 process 116 290059 : solution_invalidity.syncIteration(); 117 : 118 290059 : if (solution_invalidity.hasInvalidSolution()) 119 : { 120 690 : if (_fe_problem.acceptInvalidSolution()) 121 175 : if (_fe_problem.showInvalidSolutionConsole()) 122 171 : solution_invalidity.print(_console); 123 : else 124 4 : mooseWarning("The Solution Invalidity warnings are detected but silenced! " 125 : "Use Problem/show_invalid_solution_console=true to show solution counts"); 126 : else 127 : // output the occurrence of solution invalid in a summary table 128 515 : if (_fe_problem.showInvalidSolutionConsole()) 129 515 : solution_invalidity.print(_console); 130 : } 131 290055 : } 132 : 133 : void 134 5884090 : SolverSystem::compute(const ExecFlagType type) 135 : { 136 : // Let's try not to overcompute 137 5884090 : bool compute_tds = false; 138 5884090 : if (type == EXEC_LINEAR) 139 3132849 : compute_tds = true; 140 2751241 : else if (type == EXEC_NONLINEAR) 141 : { 142 492387 : if (_fe_problem.computingScalingJacobian() || matrixFromColoring()) 143 762 : compute_tds = true; 144 : } 145 2258854 : else if ((type == EXEC_TIMESTEP_END) || (type == EXEC_FINAL)) 146 : { 147 352143 : if (_fe_problem.solverParams(number())._type == Moose::ST_LINEAR) 148 : // We likely don't have a final residual evaluation upon which we compute the time derivatives 149 : // so we need to do so now 150 10683 : compute_tds = true; 151 : } 152 : 153 5884090 : if (compute_tds && _fe_problem.dt() > 0.) 154 5466555 : for (auto & ti : _time_integrators) 155 : { 156 : // avoid division by dt which might be zero. 157 2732594 : ti->preStep(); 158 2732594 : ti->computeTimeDerivatives(); 159 : } 160 5884090 : }