https://mooseframework.inl.gov
MatrixSymmetryCheck.C
Go to the documentation of this file.
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 
22 
25 {
27  params.addClassDescription("Report whether a matrix is symmetric or not.");
28  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  params.addParam<Real>(
32  "symmetry_tol", 1e-8, "The tolerance (both relative and absolute) for comparing symmetry");
33  params.addParam<unsigned int>(
34  "mat_number_to_load",
35  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  return params;
39 }
40 
42  : GeneralPostprocessor(parameters),
43  _mat_from_file(isParamValid("mat")),
44  _mat_file_name(_mat_from_file ? getParam<std::string>("mat") : ""),
45  _symm_tol(getParam<Real>("symmetry_tol")),
46  _mat_number_to_load(getParam<unsigned int>("mat_number_to_load")),
47  _equiv(true)
48 {
49  if (!_mat_from_file && isParamSetByUser("mat_number_to_load"))
50  paramError("mat_number_to_load",
51  "This parameter should only be set in conjunction with the 'mat' parameter");
52 }
53 
54 void
56 {
57  _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  std::unique_ptr<SparseMatrix<Number>> file_mat_wrapper;
64  if (_mat_from_file)
65  {
68  mat = file_mat_wrapper.get();
69  }
70  else
71  {
72  auto * const nl_solver = _fe_problem.getNonlinearSystemBase(0).nonlinearSolver();
73  mooseAssert(nl_solver, "This should be non-null");
74  auto & sys_mat = nl_solver->system().get_system_matrix();
75  mat = &sys_mat;
76  }
77 
78  for (const auto i : make_range(mat->row_start(), mat->row_stop()))
79  for (const auto j : make_range(mat->col_start(), mat->col_stop()))
80  {
81  const auto val1 = (*mat)(i, j);
82  const auto val2 = (*mat)(j, i);
83  if (!MooseUtils::relativeFuzzyEqual(val1, val2, _symm_tol) &&
85  {
86  _equiv = false;
87  goto endDoubleLoop;
88  }
89  }
90 
91 endDoubleLoop:
93  if (_mat_from_file)
94  LibmeshPetscCallA(_communicator.get(), MatDestroy(&file_mat));
95 }
96 
97 Real
99 {
100  return _equiv;
101 }
bool _equiv
Whether the matrix is symmetric.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:380
const unsigned int _mat_number_to_load
A binary file may contain multiple writes of a matrix.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
std::unique_ptr< PetscMatrix< Number > > createMatrixFromFile(const libMesh::Parallel::Communicator &comm, Mat &petsc_mat, const std::string &binary_mat_file, unsigned int mat_number_to_load=1)
Create a matrix from a binary file.
virtual libMesh::NonlinearSolver< Number > * nonlinearSolver()=0
const Parallel::Communicator & _communicator
This class is here to combine the Postprocessor interface and the base class Postprocessor object alo...
virtual Real getValue() const override
This will get called to actually grab the final value the postprocessor has calculated.
virtual void execute() override
Execute method.
virtual numeric_index_type row_stop() const =0
registerMooseObject("MooseApp", MatrixSymmetryCheck)
static InputParameters validParams()
MatrixSymmetryCheck(const InputParameters &parameters)
void min(const T &r, T &o, Request &req) const
const bool _mat_from_file
Whether the matrix we are checking for symmetry is from a file.
virtual numeric_index_type col_stop() const =0
virtual numeric_index_type col_start() const =0
const std::string _mat_file_name
The matrix from file name. Empty string if _mat_from_file is false.
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Checks whether the nonlinear system matrix is symmetric.
bool isParamSetByUser(const std::string &nm) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
const Real _symm_tol
Tolerance for the comparison between coefficients and transpose counterparts.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
Definition: UserObject.h:211
virtual numeric_index_type row_start() const =0
bool relativeFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within a relative tolerance.
Definition: MooseUtils.h:492
IntRange< T > make_range(T beg, T end)
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
static InputParameters validParams()
void ErrorVector unsigned int