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 "MooseStaticCondensationPreconditioner.h" 11 : 12 : #include "FEProblem.h" 13 : #include "MooseUtils.h" 14 : #include "NonlinearSystemBase.h" 15 : #include "MooseVariableFieldBase.h" 16 : #include "libmesh/implicit_system.h" 17 : #include "libmesh/static_condensation_dof_map.h" 18 : 19 : registerMooseObjectAliased("MooseApp", MooseStaticCondensationPreconditioner, "StaticCondensation"); 20 : 21 : InputParameters 22 28720 : MooseStaticCondensationPreconditioner::validParams() 23 : { 24 28720 : InputParameters params = SingleMatrixPreconditioner::validParams(); 25 57440 : params.addClassDescription("Static condensation preconditioner"); 26 57440 : params.set<bool>("full") = true; 27 57440 : params.suppressParameter<bool>("full"); 28 114880 : params.addParam<std::vector<NonlinearVariableName>>( 29 : "dont_condense_vars", 30 : {}, 31 : "A list of variables for whom to not statically condense their degrees of freedom out of the " 32 : "system. By default all degrees of freedom on element interiors are condensed out."); 33 : // Need to make this non-defaulted so that isParamValid doesn't always return true 34 86160 : params.set<MooseEnum>("mffd_type") = ""; 35 28720 : return params; 36 0 : } 37 : 38 : std::string 39 120 : MooseStaticCondensationPreconditioner::prefix() const 40 : { 41 : // We always prefix the condensed system with the nonlinear system name regardless of the number 42 : // of systems in the problem. Maybe we'll change this later for more consistency? 43 120 : return _nl.name() + "_condensed_"; 44 : } 45 : 46 95 : MooseStaticCondensationPreconditioner::MooseStaticCondensationPreconditioner( 47 95 : const InputParameters & params) 48 95 : : SingleMatrixPreconditioner(params) 49 : { 50 190 : auto check_param = [this](const auto & param_name) 51 : { 52 570 : if (isParamValid(param_name)) 53 0 : paramError(param_name, 54 : "This class prefixes every PETSc option so that it applies to the condensed " 55 : "system. Given that, there are multiple issues with setting '", 56 : param_name, 57 : "': 1) it applies to the nonlinear solver algorithm whereas the prefix this class " 58 : "applies makes PETSc options conceptually applicable only to the linear solve of " 59 : "the statically condensed system 2) these are singleton MOOSE-wrapped PETSc " 60 : "options. Consequently even if having multiple prefixes for a system's nonlinear " 61 : "solver options made sense, we don't support it. E.g. if you specify '", 62 : param_name, 63 : "' in both this object's block and the Executioner block, then there will be a " 64 : "logical conflict"); 65 285 : }; 66 95 : check_param("mffd_type"); 67 95 : check_param("solve_type"); 68 : 69 : // Now check the solve type set in the Executioner 70 95 : if (_fe_problem.solverParams(_nl.number())._type != Moose::ST_PJFNK) 71 0 : mooseError( 72 : "Static condensation preconditioning should use a PJFNK solve type. This is because it " 73 : "provides a means to compute the action of the Jacobian on vectors, which we otherwise " 74 : "would not have because when using static condensation, the Jacobian is never formed. Note " 75 : "that actions of the Jacobian on a vector are necessary for things like: GMRES, printing " 76 : "of linear residuals, or application of line searches like cubic backtracking. These " 77 : "particular operations can be avoided by using '-ksp_type preonly', disabling printing of " 78 : "linear residuals, and using the 'cp' or 'basic' line search."); 79 : 80 95 : auto * const implicit_sys = dynamic_cast<libMesh::ImplicitSystem *>(&_nl.system()); 81 95 : if (!implicit_sys) 82 0 : mooseError("Static condensation can only be used with implicit systems"); 83 95 : implicit_sys->create_static_condensation(); 84 95 : _sc_dof_map = &implicit_sys->get_dof_map().get_static_condensation(); 85 95 : _sc_system_matrix = &implicit_sys->get_static_condensation(); 86 95 : std::unordered_set<unsigned int> uncondensed_vars; 87 295 : for (auto & nl_var_name : getParam<std::vector<NonlinearVariableName>>("dont_condense_vars")) 88 10 : uncondensed_vars.insert(_nl.getVariable(0, nl_var_name).number()); 89 95 : _sc_dof_map->dont_condense_vars(uncondensed_vars); 90 95 : } 91 : 92 : void 93 95 : MooseStaticCondensationPreconditioner::initialSetup() 94 : { 95 95 : Moose::PetscSupport::storePetscOptions(_fe_problem, prefix(), *this); 96 95 : }