LCOV - code coverage report
Current view: top level - src/preconditioners - MoosePreconditioner.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 55 59 93.2 %
Date: 2025-07-17 01:28:37 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          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             : // MOOSE includes
      11             : #include "MoosePreconditioner.h"
      12             : #include "FEProblem.h"
      13             : #include "PetscSupport.h"
      14             : #include "NonlinearSystem.h"
      15             : 
      16             : #include "libmesh/coupling_matrix.h"
      17             : #include "libmesh/numeric_vector.h"
      18             : 
      19             : InputParameters
      20      112610 : MoosePreconditioner::validParams()
      21             : {
      22      112610 :   InputParameters params = MooseObject::validParams();
      23      112610 :   params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
      24             : 
      25      112610 :   MooseEnum pc_side("left right symmetric default", "default");
      26      112610 :   params.addParam<MooseEnum>("pc_side", pc_side, "Preconditioning side");
      27      112610 :   MooseEnum ksp_norm("none preconditioned unpreconditioned natural default", "unpreconditioned");
      28      112610 :   params.addParam<MooseEnum>(
      29             :       "ksp_norm", ksp_norm, "Sets the norm that is used for convergence testing");
      30      112610 :   params.registerBase("MoosePreconditioner");
      31             : 
      32      112610 :   params.addParam<std::vector<NonlinearVariableName>>(
      33             :       "off_diag_row",
      34             :       "The variable names for the off-diagonal rows you want to add into the matrix; they will be "
      35             :       "associated with an off-diagonal column from the same position in off_diag_column.");
      36      112610 :   params.addParam<std::vector<NonlinearVariableName>>(
      37             :       "off_diag_column",
      38             :       "The variable names for the off-diagonal columns you want to add into the matrix; they "
      39             :       "will be associated with an off-diagonal row from the same position in off_diag_row.");
      40      337830 :   params.addParam<bool>("full",
      41      225220 :                         false,
      42             :                         "Set to true if you want the full set of couplings between variables "
      43             :                         "simply for convenience so you don't have to set every off_diag_row "
      44             :                         "and off_diag_column combination.");
      45      112610 :   params.addParam<NonlinearSystemName>(
      46             :       "nl_sys",
      47             :       "The nonlinear system whose linearization this preconditioner should be applied to.");
      48             : 
      49      112610 :   params += Moose::PetscSupport::getPetscValidParams();
      50             : 
      51      225220 :   return params;
      52      112610 : }
      53             : 
      54       13492 : MoosePreconditioner::MoosePreconditioner(const InputParameters & params)
      55             :   : MooseObject(params),
      56             :     Restartable(this, "Preconditioners"),
      57             :     PerfGraphInterface(this),
      58       13492 :     _fe_problem(*params.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
      59       13492 :     _nl_sys_num(
      60       13492 :         isParamValid("nl_sys") ? _fe_problem.nlSysNum(getParam<NonlinearSystemName>("nl_sys")) : 0),
      61       26984 :     _nl(_fe_problem.getNonlinearSystemBase(_nl_sys_num))
      62             : {
      63       13492 :   _nl.setPCSide(getParam<MooseEnum>("pc_side"));
      64             : 
      65       13492 :   _nl.setMooseKSPNormType(getParam<MooseEnum>("ksp_norm"));
      66             : 
      67       13492 :   bool full = getParam<bool>("full");
      68             : 
      69             :   // We either have a full coupling or a custom coupling
      70       13492 :   if (full && isParamValid("off_diag_row"))
      71           0 :     paramError("off_diag_row", "Set full=false to specify the off-diagonal rows manually");
      72       13492 :   if (full && isParamValid("off_diag_column"))
      73           0 :     paramError("off_diag_column", "Set full=false to specify the off-diagonal columns manually");
      74             : 
      75             :   // Off-diagonal rows and colums must match
      76       13492 :   if (isParamValid("off_diag_row"))
      77             :   {
      78          90 :     if (isParamValid("off_diag_column"))
      79             :     {
      80             :       const auto off_diag =
      81          90 :           getParam<NonlinearVariableName, NonlinearVariableName>("off_diag_row", "off_diag_column");
      82          90 :     }
      83             :     else
      84           0 :       paramError("off_diag_row",
      85             :                  "If off-diagonal rows are specified, matching off-diagonal "
      86             :                  "columns must be specified as well");
      87             :   }
      88       13402 :   else if (isParamValid("off_diag_column"))
      89           0 :     paramError("off_diag_column",
      90             :                "If off-diagonal columns are specified, matching off-diagonal "
      91             :                "rows must be specified as well");
      92             : 
      93             :   // This must be set early because the solve type is queried by later actions
      94       13492 :   Moose::PetscSupport::setSolveTypeFromParams(_fe_problem, params);
      95       13492 : }
      96             : 
      97             : void
      98       11456 : MoosePreconditioner::copyVarValues(MeshBase & mesh,
      99             :                                    const unsigned int from_system,
     100             :                                    const unsigned int from_var,
     101             :                                    const NumericVector<Number> & from_vector,
     102             :                                    const unsigned int to_system,
     103             :                                    const unsigned int to_var,
     104             :                                    NumericVector<Number> & to_vector)
     105             : {
     106     1429088 :   for (auto & node : mesh.local_node_ptr_range())
     107             :   {
     108      708816 :     unsigned int n_comp = node->n_comp(from_system, from_var);
     109             : 
     110             :     mooseAssert(node->n_comp(from_system, from_var) == node->n_comp(to_system, to_var),
     111             :                 "Number of components does not match in each system");
     112             : 
     113     1410632 :     for (unsigned int i = 0; i < n_comp; i++)
     114             :     {
     115      701816 :       dof_id_type from_dof = node->dof_number(from_system, from_var, i);
     116      701816 :       dof_id_type to_dof = node->dof_number(to_system, to_var, i);
     117             : 
     118      701816 :       to_vector.set(to_dof, from_vector(from_dof));
     119             :     }
     120       11456 :   }
     121             : 
     122     1194336 :   for (auto & elem : as_range(mesh.local_elements_begin(), mesh.local_elements_end()))
     123             :   {
     124      591440 :     unsigned int n_comp = elem->n_comp(from_system, from_var);
     125             : 
     126             :     mooseAssert(elem->n_comp(from_system, from_var) == elem->n_comp(to_system, to_var),
     127             :                 "Number of components does not match in each system");
     128             : 
     129      609360 :     for (unsigned int i = 0; i < n_comp; i++)
     130             :     {
     131       17920 :       dof_id_type from_dof = elem->dof_number(from_system, from_var, i);
     132       17920 :       dof_id_type to_dof = elem->dof_number(to_system, to_var, i);
     133             : 
     134       17920 :       to_vector.set(to_dof, from_vector(from_dof));
     135             :     }
     136       11456 :   }
     137       11456 : }
     138             : 
     139             : void
     140       13492 : MoosePreconditioner::setCouplingMatrix(std::unique_ptr<CouplingMatrix> cm)
     141             : {
     142       13492 :   _fe_problem.setCouplingMatrix(std::move(cm), _nl_sys_num);
     143       13492 : }
     144             : 
     145             : void
     146       13095 : MoosePreconditioner::initialSetup()
     147             : {
     148       13095 :   Moose::PetscSupport::storePetscOptions(_fe_problem, _nl.prefix(), *this);
     149       13095 : }

Generated by: LCOV version 1.14