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 62767 : SolverSystem::SolverSystem(SubProblem & subproblem, 18 : FEProblemBase & fe_problem, 19 : const std::string & name, 20 62767 : Moose::VarKindType var_kind) 21 : : SystemBase(subproblem, fe_problem, name, var_kind), 22 62767 : _current_solution(nullptr), 23 62767 : _pc_side(Moose::PCS_DEFAULT), 24 62767 : _ksp_norm(Moose::KSPN_UNPRECONDITIONED), 25 62767 : _solution_is_invalid(false) 26 : { 27 62767 : } 28 : 29 58439 : SolverSystem::~SolverSystem() = default; 30 : 31 : void 32 60869 : SolverSystem::preInit() 33 : { 34 60869 : SystemBase::preInit(); 35 : 36 60869 : _current_solution = system().current_local_solution.get(); 37 : 38 60869 : if (_serialized_solution.get()) 39 39 : _serialized_solution->init(system().n_dofs(), false, SERIAL); 40 60869 : } 41 : 42 : void 43 5306 : SolverSystem::restoreSolutions() 44 : { 45 : // call parent 46 5306 : SystemBase::restoreSolutions(); 47 : // and update _current_solution 48 5306 : _current_solution = system().current_local_solution.get(); 49 5306 : } 50 : 51 : void 52 4095 : SolverSystem::serializeSolution() 53 : { 54 4095 : if (_serialized_solution.get()) 55 : { 56 4095 : if (!_serialized_solution->initialized() || _serialized_solution->size() != system().n_dofs()) 57 : { 58 63 : _serialized_solution->clear(); 59 63 : _serialized_solution->init(system().n_dofs(), false, SERIAL); 60 : } 61 : 62 4095 : _current_solution->localize(*_serialized_solution); 63 : } 64 4095 : } 65 : 66 : void 67 3878768 : SolverSystem::setSolution(const NumericVector<Number> & soln) 68 : { 69 3878768 : _current_solution = &soln; 70 : 71 3878768 : auto tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG); 72 3878768 : associateVectorToTag(const_cast<NumericVector<Number> &>(soln), tag); 73 : 74 3878768 : if (_serialized_solution.get()) 75 4095 : serializeSolution(); 76 3878768 : } 77 : 78 : void 79 14426 : SolverSystem::setPCSide(MooseEnum pcs) 80 : { 81 14426 : if (pcs == "left") 82 0 : _pc_side = Moose::PCS_LEFT; 83 14426 : else if (pcs == "right") 84 0 : _pc_side = Moose::PCS_RIGHT; 85 14426 : else if (pcs == "symmetric") 86 0 : _pc_side = Moose::PCS_SYMMETRIC; 87 14426 : else if (pcs == "default") 88 14426 : _pc_side = Moose::PCS_DEFAULT; 89 : else 90 0 : mooseError("Unknown PC side specified."); 91 14426 : } 92 : 93 : void 94 14426 : SolverSystem::setMooseKSPNormType(MooseEnum kspnorm) 95 : { 96 14426 : if (kspnorm == "none") 97 0 : _ksp_norm = Moose::KSPN_NONE; 98 14426 : else if (kspnorm == "preconditioned") 99 0 : _ksp_norm = Moose::KSPN_PRECONDITIONED; 100 14426 : else if (kspnorm == "unpreconditioned") 101 14426 : _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 14426 : } 109 : 110 : void 111 316410 : SolverSystem::checkInvalidSolution() 112 : { 113 316410 : auto & solution_invalidity = _app.solutionInvalidity(); 114 : 115 : // sync all solution invalid counts to rank 0 process 116 316410 : solution_invalidity.syncIteration(); 117 : 118 316410 : if (solution_invalidity.hasInvalidSolution()) 119 : { 120 691 : if (_fe_problem.acceptInvalidSolution()) 121 176 : if (_fe_problem.showInvalidSolutionConsole()) 122 172 : 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 316406 : } 132 : 133 : void 134 6372299 : SolverSystem::compute(const ExecFlagType type) 135 : { 136 : // Let's try not to overcompute 137 6372299 : bool compute_tds = false; 138 6372299 : if (type == EXEC_LINEAR) 139 3377335 : compute_tds = true; 140 2994964 : else if (type == EXEC_NONLINEAR) 141 : { 142 534001 : if (_fe_problem.computingScalingJacobian() || matrixFromColoring()) 143 796 : compute_tds = true; 144 : } 145 2460963 : else if ((type == EXEC_TIMESTEP_END) || (type == EXEC_FINAL)) 146 : { 147 384511 : 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 11409 : compute_tds = true; 151 : } 152 : 153 6372299 : if (compute_tds && _fe_problem.dt() > 0.) 154 5912056 : for (auto & ti : _time_integrators) 155 : { 156 : // avoid division by dt which might be zero. 157 2954636 : ti->preStep(); 158 2954636 : ti->computeTimeDerivatives(); 159 : } 160 6372299 : }