LCOV - code coverage report
Current view: top level - src/preconditioners - SingleMatrixPreconditioner.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 41 45 91.1 %
Date: 2025-08-08 20:01:16 Functions: 2 2 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             : #include "SingleMatrixPreconditioner.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "FEProblem.h"
      14             : #include "MooseUtils.h"
      15             : #include "MooseVariableFE.h"
      16             : #include "NonlinearSystem.h"
      17             : 
      18             : #include "libmesh/coupling_matrix.h"
      19             : 
      20             : registerMooseObjectAliased("MooseApp", SingleMatrixPreconditioner, "SMP");
      21             : 
      22             : InputParameters
      23       56624 : SingleMatrixPreconditioner::validParams()
      24             : {
      25       56624 :   InputParameters params = MoosePreconditioner::validParams();
      26             : 
      27       56624 :   params.addClassDescription("Single matrix preconditioner (SMP) builds a preconditioner using "
      28             :                              "user defined off-diagonal parts of the Jacobian.");
      29             : 
      30       56624 :   params.addParam<std::vector<NonlinearVariableName>>(
      31             :       "coupled_groups",
      32             :       {},
      33             :       "List multiple space separated groups of comma separated variables. "
      34             :       "Off-diagonal jacobians will be generated for all pairs within a group.");
      35      169872 :   params.addParam<bool>(
      36             :       "trust_my_coupling",
      37      113248 :       false,
      38             :       "Whether to trust my coupling even if the framework wants to be paranoid and create a full "
      39             :       "coupling matrix, which can happen when using global AD indexing for example.");
      40             : 
      41       56624 :   return params;
      42           0 : }
      43             : 
      44       14029 : SingleMatrixPreconditioner::SingleMatrixPreconditioner(const InputParameters & params)
      45       14029 :   : MoosePreconditioner(params)
      46             : {
      47       14029 :   NonlinearSystemBase & nl = _fe_problem.getNonlinearSystemBase(_nl_sys_num);
      48       14029 :   unsigned int n_vars = nl.nVariables();
      49       14029 :   const auto & libmesh_system = nl.system();
      50       14029 :   auto cm = std::make_unique<CouplingMatrix>(n_vars);
      51             : 
      52       14029 :   if (!getParam<bool>("full"))
      53             :   {
      54             :     // put 1s on diagonal
      55        1073 :     for (unsigned int i = 0; i < n_vars; ++i)
      56         608 :       (*cm)(i, i) = 1;
      57             : 
      58             :     // off-diagonal entries from the off_diag_row and off_diag_column parameters
      59         465 :     for (const auto & off_diag :
      60         974 :          getParam<NonlinearVariableName, NonlinearVariableName>("off_diag_row", "off_diag_column"))
      61             :     {
      62          44 :       const auto row = libmesh_system.variable_number(off_diag.first);
      63          44 :       const auto column = libmesh_system.variable_number(off_diag.second);
      64          44 :       (*cm)(row, column) = 1;
      65         465 :     }
      66             : 
      67             :     // off-diagonal entries from the coupled_groups parameters
      68         465 :     const auto & all_vars = nl.getVariableNames();
      69         491 :     for (const auto & group : getParam<std::vector<NonlinearVariableName>>("coupled_groups"))
      70             :     {
      71          26 :       std::vector<VariableName> vars;
      72          26 :       MooseUtils::tokenize(group, vars, 1, ",");
      73             :       try
      74             :       {
      75          26 :         MooseUtils::expandAllMatches(all_vars, vars);
      76             :       }
      77           0 :       catch (std::invalid_argument const & e)
      78             :       {
      79           0 :         mooseError("No variable name match found for '", e.what(), "'.");
      80           0 :       }
      81             : 
      82          78 :       for (const auto j : index_range(vars))
      83          78 :         for (unsigned int k = j + 1; k < vars.size(); ++k)
      84             :         {
      85          26 :           const auto row = libmesh_system.variable_number(vars[j]);
      86          26 :           const auto column = libmesh_system.variable_number(vars[k]);
      87          26 :           (*cm)(row, column) = 1;
      88          26 :           (*cm)(column, row) = 1;
      89             :         }
      90          26 :     }
      91             :   }
      92             :   else
      93             :   {
      94       34284 :     for (unsigned int i = 0; i < n_vars; ++i)
      95       61588 :       for (unsigned int j = 0; j < n_vars; ++j)
      96       40868 :         (*cm)(i, j) = 1;
      97             :   }
      98             : 
      99       14029 :   setCouplingMatrix(std::move(cm));
     100       14029 :   if (getParam<bool>("trust_my_coupling"))
     101           4 :     _fe_problem.trustUserCouplingMatrix();
     102       14029 : }

Generated by: LCOV version 1.14