LCOV - code coverage report
Current view: top level - src/postprocessors - MatrixSymmetryCheck.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 42 44 95.5 %
Date: 2025-07-17 01:28:37 Functions: 4 4 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 "MatrixSymmetryCheck.h"
      11             : 
      12             : #include "FEProblem.h"
      13             : #include "NonlinearSystemBase.h"
      14             : 
      15             : #include "libmesh/nonlinear_solver.h"
      16             : #include "libmesh/nonlinear_implicit_system.h"
      17             : #include "libmesh/petsc_matrix.h"
      18             : 
      19             : #include <petscmat.h>
      20             : 
      21             : registerMooseObject("MooseApp", MatrixSymmetryCheck);
      22             : 
      23             : InputParameters
      24       14433 : MatrixSymmetryCheck::validParams()
      25             : {
      26       14433 :   InputParameters params = GeneralPostprocessor::validParams();
      27       14433 :   params.addClassDescription("Report whether a matrix is symmetric or not.");
      28       14433 :   params.addParam<std::string>("mat",
      29             :                                "The petsc binary mat file containing the matrix. If this "
      30             :                                "parameter is not provided, then the system matrix is used");
      31       43299 :   params.addParam<Real>(
      32       28866 :       "symmetry_tol", 1e-8, "The tolerance (both relative and absolute) for comparing symmetry");
      33       43299 :   params.addParam<unsigned int>(
      34             :       "mat_number_to_load",
      35       28866 :       1,
      36             :       "A binary file may contain multiple writes of a matrix. This parameter can be used to load a "
      37             :       "particular matrix from the binary file. By default we load the first written matrix");
      38       14433 :   return params;
      39           0 : }
      40             : 
      41          84 : MatrixSymmetryCheck::MatrixSymmetryCheck(const InputParameters & parameters)
      42             :   : GeneralPostprocessor(parameters),
      43          84 :     _mat_from_file(isParamValid("mat")),
      44          84 :     _mat_file_name(_mat_from_file ? getParam<std::string>("mat") : ""),
      45          84 :     _symm_tol(getParam<Real>("symmetry_tol")),
      46          84 :     _mat_number_to_load(getParam<unsigned int>("mat_number_to_load")),
      47          84 :     _equiv(true)
      48             : {
      49          84 :   if (!_mat_from_file && isParamSetByUser("mat_number_to_load"))
      50           0 :     paramError("mat_number_to_load",
      51             :                "This parameter should only be set in conjunction with the 'mat' parameter");
      52          84 : }
      53             : 
      54             : void
      55          77 : MatrixSymmetryCheck::execute()
      56             : {
      57          77 :   _equiv = true;
      58             :   // Pointer to the matrix we are analyzing for symmetry
      59             :   const SparseMatrix<Number> * mat;
      60             :   // Petsc matrix from file
      61             :   Mat file_mat;
      62             : 
      63          77 :   std::unique_ptr<SparseMatrix<Number>> file_mat_wrapper;
      64          77 :   if (_mat_from_file)
      65             :   {
      66          44 :     file_mat_wrapper = Moose::PetscSupport::createMatrixFromFile(
      67          44 :         _communicator, file_mat, _mat_file_name, _mat_number_to_load);
      68          44 :     mat = file_mat_wrapper.get();
      69             :   }
      70             :   else
      71             :   {
      72          33 :     auto * const nl_solver = _fe_problem.getNonlinearSystemBase(0).nonlinearSolver();
      73             :     mooseAssert(nl_solver, "This should be non-null");
      74          33 :     auto & sys_mat = nl_solver->system().get_system_matrix();
      75          33 :     mat = &sys_mat;
      76             :   }
      77             : 
      78       13597 :   for (const auto i : make_range(mat->row_start(), mat->row_stop()))
      79     5397040 :     for (const auto j : make_range(mat->col_start(), mat->col_stop()))
      80             :     {
      81     5383520 :       const auto val1 = (*mat)(i, j);
      82     5383520 :       const auto val2 = (*mat)(j, i);
      83     5386790 :       if (!MooseUtils::relativeFuzzyEqual(val1, val2, _symm_tol) &&
      84        3270 :           !MooseUtils::absoluteFuzzyEqual(val1, val2, _symm_tol))
      85             :       {
      86          22 :         _equiv = false;
      87          22 :         goto endDoubleLoop;
      88             :       }
      89             :     }
      90             : 
      91          77 : endDoubleLoop:
      92          77 :   _communicator.min(_equiv);
      93          77 :   if (_mat_from_file)
      94          44 :     LibmeshPetscCallA(_communicator.get(), MatDestroy(&file_mat));
      95          77 : }
      96             : 
      97             : Real
      98          77 : MatrixSymmetryCheck::getValue() const
      99             : {
     100          77 :   return _equiv;
     101             : }

Generated by: LCOV version 1.14