LCOV - code coverage report
Current view: top level - src/postprocessors - MatrixEigenvalueCheck.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 47 56 83.9 %
Date: 2025-08-14 10:14:56 Functions: 6 6 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 "MatrixEigenvalueCheck.h"
      11             : 
      12             : #include <petscmat.h>
      13             : #include <slepceps.h>
      14             : 
      15             : registerMooseObject("NavierStokesApp", MatrixEigenvalueCheck);
      16             : 
      17             : InputParameters
      18         288 : MatrixEigenvalueCheck::validParams()
      19             : {
      20         288 :   InputParameters params = GeneralPostprocessor::validParams();
      21         288 :   params.addClassDescription("Report the number of zero eigenvalues of a matrix.");
      22         576 :   params.addRequiredParam<std::string>("mat", "The petsc binary mat file containing the matrix");
      23         576 :   params.addParam<Real>("zero_tol", 1e-8, "The tolerance for determining zero values");
      24         576 :   params.addParam<bool>("print", false, "Whether to print the eigensolves to the console");
      25         288 :   return params;
      26           0 : }
      27             : 
      28         144 : MatrixEigenvalueCheck::MatrixEigenvalueCheck(const InputParameters & parameters)
      29             :   : GeneralPostprocessor(parameters),
      30         144 :     _zero_tol(getParam<Real>("zero_tol")),
      31         288 :     _mat_name(getParam<std::string>("mat")),
      32         432 :     _print(getParam<bool>("print"))
      33             : {
      34         144 : }
      35             : 
      36             : void
      37         108 : MatrixEigenvalueCheck::initialize()
      38             : {
      39             :   PetscViewer matviewer;
      40             : 
      41         108 :   LibmeshPetscCallA(_communicator.get(), MatCreate(_communicator.get(), &_petsc_mat));
      42         108 :   LibmeshPetscCallA(
      43             :       _communicator.get(),
      44             :       PetscViewerBinaryOpen(_communicator.get(), _mat_name.c_str(), FILE_MODE_READ, &matviewer));
      45         108 :   LibmeshPetscCallA(_communicator.get(), MatLoad(_petsc_mat, matviewer));
      46         108 :   LibmeshPetscCallA(_communicator.get(), PetscViewerDestroy(&matviewer));
      47             : 
      48         108 :   _num_zero_eigenvalues = 0;
      49         108 : }
      50             : 
      51             : void
      52         108 : MatrixEigenvalueCheck::execute()
      53             : {
      54         108 :   if (_print)
      55           0 :     _console << std::endl << "Conducting eigen-solve for " << _mat_name << std::endl;
      56             : 
      57             :   PetscScalar kr, ki;
      58             :   PetscReal error, re, im;
      59             :   PetscInt nconv, nev, i;
      60             :   EPS eps;
      61             : 
      62         108 :   LibmeshPetscCallA(_communicator.get(), EPSCreate(_communicator.get(), &eps));
      63         108 :   LibmeshPetscCallA(_communicator.get(), EPSSetOperators(eps, _petsc_mat, nullptr));
      64         108 :   LibmeshPetscCallA(_communicator.get(), EPSSetType(eps, EPSLAPACK));
      65         108 :   LibmeshPetscCallA(_communicator.get(), EPSSolve(eps));
      66         108 :   LibmeshPetscCallA(_communicator.get(), EPSGetDimensions(eps, &nev, nullptr, nullptr));
      67         108 :   if (_print)
      68             :   {
      69           0 :     LibmeshPetscCallA(_communicator.get(),
      70             :                       PetscPrintf(_communicator.get(),
      71             :                                   " Number of requested eigenvalues: %" PetscInt_FMT "\n",
      72             :                                   nev));
      73             :   }
      74             : 
      75         108 :   LibmeshPetscCallA(_communicator.get(), EPSGetConverged(eps, &nconv));
      76         108 :   if (_print)
      77             :   {
      78           0 :     LibmeshPetscCallA(_communicator.get(),
      79             :                       PetscPrintf(_communicator.get(),
      80             :                                   " Number of converged eigenpairs: %" PetscInt_FMT "\n\n",
      81             :                                   nconv));
      82             :   }
      83             : 
      84         108 :   if (nconv > 0)
      85             :   {
      86         108 :     if (_print)
      87             :     {
      88             :       /*
      89             :          Display eigenvalues and relative errors
      90             :       */
      91           0 :       LibmeshPetscCallA(_communicator.get(),
      92             :                         PetscPrintf(_communicator.get(),
      93             :                                     "           k          ||Ax-kx||/||kx||\n"
      94             :                                     "   ----------------- ------------------\n"));
      95             :     }
      96             : 
      97       35658 :     for (i = 0; i < nconv; i++)
      98             :     {
      99             :       /*
     100             :         Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and
     101             :         ki (imaginary part)
     102             :       */
     103       35550 :       LibmeshPetscCallA(_communicator.get(), EPSGetEigenpair(eps, i, &kr, &ki, nullptr, nullptr));
     104             :       /*
     105             :          Compute the relative error associated to each eigenpair
     106             :       */
     107       35550 :       LibmeshPetscCallA(_communicator.get(), EPSComputeError(eps, i, EPS_ERROR_RELATIVE, &error));
     108             : 
     109             : #if defined(PETSC_USE_COMPLEX)
     110             :       re = PetscRealPart(kr);
     111             :       im = PetscImaginaryPart(kr);
     112             : #else
     113       35550 :       re = kr;
     114       35550 :       im = ki;
     115             : #endif
     116       35550 :       const bool zero_im = std::abs(im) < _zero_tol;
     117       35550 :       const bool zero_re = std::abs(re) < _zero_tol;
     118       35550 :       if (_print)
     119             :       {
     120           0 :         if (!zero_im)
     121           0 :           LibmeshPetscCallA(
     122             :               _communicator.get(),
     123             :               PetscPrintf(
     124             :                   PETSC_COMM_WORLD, " %9f+%9fi %12g\n", (double)re, (double)im, (double)error));
     125             :         else
     126           0 :           LibmeshPetscCallA(
     127             :               _communicator.get(),
     128             :               PetscPrintf(_communicator.get(), "   %12f       %12g\n", (double)re, (double)error));
     129             :       }
     130       35550 :       if (zero_im && zero_re)
     131       13086 :         ++_num_zero_eigenvalues;
     132             :     }
     133             : 
     134         108 :     if (_print)
     135             :     {
     136           0 :       LibmeshPetscCallA(_communicator.get(), PetscPrintf(_communicator.get(), "\n"));
     137             :     }
     138             :   }
     139         108 : }
     140             : 
     141             : void
     142         108 : MatrixEigenvalueCheck::finalize()
     143             : {
     144         108 : }
     145             : 
     146             : Real
     147         108 : MatrixEigenvalueCheck::getValue() const
     148             : {
     149         108 :   return _num_zero_eigenvalues;
     150             : }

Generated by: LCOV version 1.14