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 : }