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 : #include "MooseUtils.h" 15 : 16 : using namespace libMesh; 17 : 18 61914 : SolverSystem::SolverSystem(SubProblem & subproblem, 19 : FEProblemBase & fe_problem, 20 : const std::string & name, 21 61914 : Moose::VarKindType var_kind) 22 : : SystemBase(subproblem, fe_problem, name, var_kind), 23 61914 : _current_solution(nullptr), 24 61914 : _pc_side(Moose::PCS_DEFAULT), 25 61914 : _ksp_norm(Moose::KSPN_UNPRECONDITIONED) 26 : { 27 61914 : } 28 : 29 58810 : SolverSystem::~SolverSystem() = default; 30 : 31 : void 32 60128 : SolverSystem::preInit() 33 : { 34 60128 : SystemBase::preInit(); 35 : 36 60128 : _current_solution = system().current_local_solution.get(); 37 : 38 60128 : if (_serialized_solution.get()) 39 36 : _serialized_solution->init(system().n_dofs(), false, SERIAL); 40 60128 : } 41 : 42 : void 43 3297 : SolverSystem::restoreSolutions() 44 : { 45 : // call parent 46 3297 : SystemBase::restoreSolutions(); 47 : // and update _current_solution 48 3297 : _current_solution = system().current_local_solution.get(); 49 3297 : } 50 : 51 : void 52 3735 : SolverSystem::serializeSolution() 53 : { 54 3735 : if (_serialized_solution.get()) 55 : { 56 3735 : 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 3735 : _current_solution->localize(*_serialized_solution); 63 : } 64 3735 : } 65 : 66 : void 67 3618730 : SolverSystem::setSolution(const NumericVector<Number> & soln) 68 : { 69 3618730 : _current_solution = &soln; 70 : 71 3618730 : auto tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG); 72 3618730 : associateVectorToTag(const_cast<NumericVector<Number> &>(soln), tag); 73 : 74 3618730 : if (_serialized_solution.get()) 75 3735 : serializeSolution(); 76 3618730 : } 77 : 78 : void 79 21100 : SolverSystem::setFixedPointRelaxationFactor(const Real relaxation_factor) 80 : { 81 21100 : _fixed_point_relaxation_factor = relaxation_factor; 82 21100 : } 83 : 84 : void 85 21100 : SolverSystem::clearFixedPointRelaxation() 86 : { 87 21100 : _fixed_point_relaxation_factor = 1.0; 88 21100 : } 89 : 90 : void 91 21100 : SolverSystem::saveOldSolutionForFixedPointRelaxation() 92 : { 93 21100 : if (MooseUtils::absoluteFuzzyEqual(_fixed_point_relaxation_factor, 1.0)) 94 0 : return; 95 : 96 21100 : if (!hasSolutionState(1, Moose::SolutionIterationType::FixedPoint)) 97 225 : needSolutionState(1, Moose::SolutionIterationType::FixedPoint, solution().type()); 98 : 99 : // Just in case checking if someone already allocated one which does not match 100 : mooseAssert(solutionStateParallelType(1, Moose::SolutionIterationType::FixedPoint) == 101 : solution().type(), 102 : "Fixed point relaxation requires the previous fixed point solution state to have " 103 : "the same parallel type as the system solution."); 104 : 105 21100 : solutionState(1, Moose::SolutionIterationType::FixedPoint) = solution(); 106 : } 107 : 108 : void 109 21100 : SolverSystem::applyFixedPointRelaxation() 110 : { 111 21100 : if (MooseUtils::absoluteFuzzyEqual(_fixed_point_relaxation_factor, 1.0)) 112 0 : return; 113 : 114 : mooseAssert(hasSolutionState(1, Moose::SolutionIterationType::FixedPoint), 115 : "Fixed point relaxation was requested but the old fixed point solution was not " 116 : "saved."); 117 : 118 : // This might be paranoid but who knows, maybe someone requests nonghosted 119 : mooseAssert(solutionStateParallelType(1, Moose::SolutionIterationType::FixedPoint) == 120 : solution().type(), 121 : "Fixed point relaxation requires the previous fixed point solution state to have " 122 : "the same parallel type as the system solution."); 123 : 124 21100 : auto & sol = solution(); 125 21100 : sol.scale(_fixed_point_relaxation_factor); 126 42200 : sol.add(1.0 - _fixed_point_relaxation_factor, 127 21100 : solutionState(1, Moose::SolutionIterationType::FixedPoint)); 128 21100 : sol.close(); 129 21100 : update(); 130 : } 131 : 132 : void 133 13141 : SolverSystem::setPCSide(MooseEnum pcs) 134 : { 135 13141 : if (pcs == "left") 136 0 : _pc_side = Moose::PCS_LEFT; 137 13141 : else if (pcs == "right") 138 0 : _pc_side = Moose::PCS_RIGHT; 139 13141 : else if (pcs == "symmetric") 140 0 : _pc_side = Moose::PCS_SYMMETRIC; 141 13141 : else if (pcs == "default") 142 13141 : _pc_side = Moose::PCS_DEFAULT; 143 : else 144 0 : mooseError("Unknown PC side specified."); 145 13141 : } 146 : 147 : void 148 13141 : SolverSystem::setMooseKSPNormType(MooseEnum kspnorm) 149 : { 150 13141 : if (kspnorm == "none") 151 0 : _ksp_norm = Moose::KSPN_NONE; 152 13141 : else if (kspnorm == "preconditioned") 153 0 : _ksp_norm = Moose::KSPN_PRECONDITIONED; 154 13141 : else if (kspnorm == "unpreconditioned") 155 13141 : _ksp_norm = Moose::KSPN_UNPRECONDITIONED; 156 0 : else if (kspnorm == "natural") 157 0 : _ksp_norm = Moose::KSPN_NATURAL; 158 0 : else if (kspnorm == "default") 159 0 : _ksp_norm = Moose::KSPN_DEFAULT; 160 : else 161 0 : mooseError("Unknown ksp norm type specified."); 162 13141 : } 163 : 164 : void 165 313739 : SolverSystem::checkInvalidSolution() 166 : { 167 313739 : auto & solution_invalidity = _app.solutionInvalidity(); 168 : 169 : // sync all solution invalid counts to rank 0 process 170 313739 : solution_invalidity.syncIteration(); 171 : 172 313739 : if (solution_invalidity.hasInvalidSolution()) 173 : { 174 626 : if (_fe_problem.acceptInvalidSolution()) 175 164 : if (_fe_problem.showInvalidSolutionConsole()) 176 161 : solution_invalidity.print(_console); 177 : else 178 3 : mooseWarning("The Solution Invalidity warnings are detected but silenced! " 179 : "Use Problem/show_invalid_solution_console=true to show solution counts"); 180 : else 181 : // output the occurrence of solution invalid in a summary table 182 462 : if (_fe_problem.showInvalidSolutionConsole()) 183 462 : solution_invalidity.print(_console); 184 : } 185 313736 : } 186 : 187 : void 188 5923690 : SolverSystem::compute(const ExecFlagType type) 189 : { 190 : // Let's try not to overcompute 191 5923690 : bool compute_tds = false; 192 5923690 : if (type == EXEC_LINEAR) 193 3134946 : compute_tds = true; 194 2788744 : else if (type == EXEC_NONLINEAR) 195 : { 196 488812 : if (_fe_problem.computingScalingJacobian() || matrixFromColoring()) 197 654 : compute_tds = true; 198 : } 199 2299932 : else if ((type == EXEC_TIMESTEP_END) || (type == EXEC_FINAL)) 200 : { 201 365399 : if (_fe_problem.solverParams(number())._type == Moose::ST_LINEAR) 202 : // We likely don't have a final residual evaluation upon which we compute the time derivatives 203 : // so we need to do so now 204 10800 : compute_tds = true; 205 : } 206 : 207 : // avoid division by dt which might be zero. 208 5923690 : if (compute_tds && _fe_problem.dt() > 0.) 209 5454662 : for (auto & ti : _time_integrators) 210 : { 211 : // Do things like compute integration weights 212 2725461 : ti->preStep(); 213 2725461 : ti->computeTimeDerivatives(); 214 : } 215 5923690 : }