LCOV - code coverage report
Current view: top level - src/utils - ColumnMajorMatrix.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #31706 (f8ed4a) with base bb0a08 Lines: 126 167 75.4 %
Date: 2025-11-03 17:23:24 Functions: 14 51 27.5 %
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             : // MOOSE includes
      11             : #include "ColumnMajorMatrix.h"
      12             : 
      13             : #include "libmesh/petsc_macro.h"
      14             : 
      15             : // PETSc includes
      16             : #include <petscsys.h>
      17             : #include <petscblaslapack.h>
      18             : 
      19             : template <typename T>
      20        1006 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(unsigned int rows, unsigned int cols)
      21        2012 :   : _n_rows(rows), _n_cols(cols), _n_entries(rows * cols), _values(rows * cols, 0.0)
      22             : {
      23        1006 :   _values.resize(rows * cols);
      24        1006 : }
      25             : 
      26             : template <typename T>
      27         206 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(const ColumnMajorMatrixTempl<T> & rhs)
      28         206 :   : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
      29             : {
      30         206 :   *this = rhs;
      31         206 : }
      32             : 
      33             : template <typename T>
      34           2 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(const TypeTensor<T> & rhs)
      35           2 :   : _n_rows(LIBMESH_DIM),
      36           2 :     _n_cols(LIBMESH_DIM),
      37           2 :     _n_entries(LIBMESH_DIM * LIBMESH_DIM),
      38           4 :     _values(LIBMESH_DIM * LIBMESH_DIM)
      39             : {
      40           8 :   for (const auto j : make_range(Moose::dim))
      41          24 :     for (const auto i : make_range(Moose::dim))
      42          18 :       (*this)(i, j) = rhs(i, j);
      43           2 : }
      44             : 
      45             : template <typename T>
      46           0 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(const DenseMatrix<T> & rhs)
      47           0 :   : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
      48             : {
      49           0 :   *this = rhs;
      50           0 : }
      51             : 
      52             : template <typename T>
      53           0 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(const DenseVector<T> & rhs)
      54           0 :   : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
      55             : {
      56           0 :   *this = rhs;
      57           0 : }
      58             : 
      59             : template <typename T>
      60           2 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(const TypeVector<T> & col1,
      61             :                                                   const TypeVector<T> & col2,
      62             :                                                   const TypeVector<T> & col3)
      63           2 :   : _n_rows(LIBMESH_DIM),
      64           2 :     _n_cols(LIBMESH_DIM),
      65           2 :     _n_entries(LIBMESH_DIM * LIBMESH_DIM),
      66           4 :     _values(LIBMESH_DIM * LIBMESH_DIM)
      67             : {
      68           2 :   unsigned int entry = 0;
      69           8 :   for (const auto i : make_range(Moose::dim))
      70           6 :     _values[entry++] = col1(i);
      71             : 
      72           8 :   for (const auto i : make_range(Moose::dim))
      73           6 :     _values[entry++] = col2(i);
      74             : 
      75           8 :   for (const auto i : make_range(Moose::dim))
      76           6 :     _values[entry++] = col3(i);
      77           2 : }
      78             : 
      79             : template <typename T>
      80             : ColumnMajorMatrixTempl<T>
      81           4 : ColumnMajorMatrixTempl<T>::kronecker(const ColumnMajorMatrixTempl<T> & rhs) const
      82             : {
      83           4 :   rhs.checkSquareness();
      84             : 
      85           2 :   ColumnMajorMatrixTempl<T> ret_matrix(_n_rows * rhs._n_rows, _n_cols * rhs._n_cols);
      86             : 
      87           6 :   for (unsigned int i = 0; i < _n_rows; i++)
      88          12 :     for (unsigned int j = 0; j < _n_cols; j++)
      89          24 :       for (unsigned int k = 0; k < rhs._n_rows; k++)
      90          48 :         for (unsigned int l = 0; l < rhs._n_cols; l++)
      91          32 :           ret_matrix(((i * _n_rows) + k), ((j * _n_cols) + l)) = (*this)(i, j) * rhs(k, l);
      92             : 
      93           2 :   return ret_matrix;
      94           0 : }
      95             : 
      96             : template <typename T>
      97             : ColumnMajorMatrixTempl<T> &
      98           2 : ColumnMajorMatrixTempl<T>::operator=(const DenseMatrix<T> & rhs)
      99             : {
     100           2 :   if (_n_rows != rhs.m() || _n_cols != rhs.n())
     101           2 :     mooseError("ColumnMajorMatrix and DenseMatrix should be of the same shape.");
     102             : 
     103           0 :   _n_rows = rhs.m();
     104           0 :   _n_cols = rhs.n();
     105           0 :   _n_entries = rhs.m() * rhs.n();
     106           0 :   _values.resize(rhs.m() * rhs.n());
     107             : 
     108           0 :   for (unsigned int j = 0; j < _n_cols; ++j)
     109           0 :     for (unsigned int i = 0; i < _n_rows; ++i)
     110           0 :       (*this)(i, j) = rhs(i, j);
     111             : 
     112           0 :   return *this;
     113             : }
     114             : 
     115             : template <typename T>
     116             : ColumnMajorMatrixTempl<T> &
     117           2 : ColumnMajorMatrixTempl<T>::operator=(const DenseVector<T> & rhs)
     118             : {
     119           2 :   if (_n_rows != rhs.size() || _n_cols != 1)
     120           2 :     mooseError("ColumnMajorMatrix and DenseVector should be of the same shape.");
     121             : 
     122           0 :   _n_rows = rhs.size();
     123           0 :   _n_cols = 1;
     124           0 :   _n_entries = rhs.size();
     125           0 :   _values.resize(rhs.size());
     126             : 
     127           0 :   for (unsigned int i = 0; i < _n_rows; ++i)
     128           0 :     (*this)(i) = rhs(i);
     129             : 
     130           0 :   return *this;
     131             : }
     132             : 
     133             : template <typename T>
     134             : void
     135           2 : ColumnMajorMatrixTempl<T>::eigen(ColumnMajorMatrixTempl<T> & eval,
     136             :                                  ColumnMajorMatrixTempl<T> & evec) const
     137             : {
     138           2 :   this->checkSquareness();
     139             : 
     140           2 :   char jobz = 'V';
     141           2 :   char uplo = 'U';
     142           2 :   PetscBLASInt n = _n_rows;
     143           2 :   PetscBLASInt return_value = 0;
     144             : 
     145           2 :   eval._n_rows = _n_rows;
     146           2 :   eval._n_cols = 1;
     147           2 :   eval._n_entries = _n_rows;
     148           2 :   eval._values.resize(_n_rows);
     149             : 
     150           2 :   evec = *this;
     151             : 
     152           2 :   T * eval_data = eval.rawData();
     153           2 :   T * evec_data = evec.rawData();
     154             : 
     155           2 :   PetscBLASInt buffer_size = n * 64;
     156           2 :   std::vector<T> buffer(buffer_size);
     157             : 
     158           2 :   LAPACKsyev_(&jobz, &uplo, &n, evec_data, &n, eval_data, &buffer[0], &buffer_size, &return_value);
     159             : 
     160           2 :   if (return_value)
     161           0 :     mooseError("error in lapack eigen solve");
     162           2 : }
     163             : 
     164             : template <>
     165             : void
     166           0 : ColumnMajorMatrixTempl<ADReal>::eigen(ColumnMajorMatrixTempl<ADReal> &,
     167             :                                       ColumnMajorMatrixTempl<ADReal> &) const
     168             : {
     169           0 :   mooseError("Eigen solves with AD types is not supported.");
     170             : }
     171             : 
     172             : template <typename T>
     173             : void
     174           6 : ColumnMajorMatrixTempl<T>::eigenNonsym(ColumnMajorMatrixTempl<T> & eval_real,
     175             :                                        ColumnMajorMatrixTempl<T> & eval_img,
     176             :                                        ColumnMajorMatrixTempl<T> & evec_right,
     177             :                                        ColumnMajorMatrixTempl<T> & evec_left) const
     178             : {
     179           6 :   this->checkSquareness();
     180             : 
     181           6 :   ColumnMajorMatrixTempl<T> a(*this);
     182             : 
     183           6 :   char jobvl = 'V';
     184           6 :   char jobvr = 'V';
     185           6 :   PetscBLASInt n = _n_rows;
     186           6 :   PetscBLASInt return_value = 0;
     187             : 
     188           6 :   eval_real._n_rows = _n_rows;
     189           6 :   eval_real._n_cols = 1;
     190           6 :   eval_real._n_entries = _n_rows;
     191           6 :   eval_real._values.resize(_n_rows);
     192             : 
     193           6 :   eval_img._n_rows = _n_rows;
     194           6 :   eval_img._n_cols = 1;
     195           6 :   eval_img._n_entries = _n_rows;
     196           6 :   eval_img._values.resize(_n_rows);
     197             : 
     198           6 :   T * a_data = a.rawData();
     199           6 :   T * eval_r = eval_real.rawData();
     200           6 :   T * eval_i = eval_img.rawData();
     201           6 :   T * evec_ri = evec_right.rawData();
     202           6 :   T * evec_le = evec_left.rawData();
     203             : 
     204           6 :   PetscBLASInt buffer_size = n * 64;
     205           6 :   std::vector<T> buffer(buffer_size);
     206             : 
     207           6 :   LAPACKgeev_(&jobvl,
     208             :               &jobvr,
     209             :               &n,
     210             :               a_data,
     211             :               &n,
     212             :               eval_r,
     213             :               eval_i,
     214             :               evec_le,
     215             :               &n,
     216             :               evec_ri,
     217             :               &n,
     218           6 :               &buffer[0],
     219             :               &buffer_size,
     220             :               &return_value);
     221             : 
     222           6 :   if (return_value)
     223           0 :     mooseError("error in lapack eigen solve");
     224           6 : }
     225             : 
     226             : template <>
     227             : void
     228           0 : ColumnMajorMatrixTempl<ADReal>::eigenNonsym(ColumnMajorMatrixTempl<ADReal> &,
     229             :                                             ColumnMajorMatrixTempl<ADReal> &,
     230             :                                             ColumnMajorMatrixTempl<ADReal> &,
     231             :                                             ColumnMajorMatrixTempl<ADReal> &) const
     232             : {
     233           0 :   mooseError("Eigen solves with AD types is not supported.");
     234             : }
     235             : 
     236             : template <typename T>
     237             : void
     238           4 : ColumnMajorMatrixTempl<T>::exp(ColumnMajorMatrixTempl<T> & z) const
     239             : {
     240             :   using std::exp;
     241           4 :   this->checkSquareness();
     242             : 
     243           4 :   ColumnMajorMatrixTempl<T> a(*this);
     244           4 :   ColumnMajorMatrixTempl<T> evals_real(_n_rows, 1), evals_img(_n_rows, 1),
     245           4 :       evals_real2(_n_rows, _n_cols);
     246           4 :   ColumnMajorMatrixTempl<T> evec_right(_n_rows, _n_cols), evec_left(_n_rows, _n_cols);
     247           4 :   ColumnMajorMatrixTempl<T> evec_right_inverse(_n_rows, _n_cols);
     248             : 
     249           4 :   a.eigenNonsym(evals_real, evals_img, evec_right, evec_left);
     250             : 
     251          16 :   for (unsigned int i = 0; i < _n_rows; i++)
     252          12 :     evals_real2(i, i) = exp(evals_real(i, 0));
     253             : 
     254           4 :   evec_right.inverse(evec_right_inverse);
     255             : 
     256           4 :   z = evec_right * evals_real2 * evec_right_inverse;
     257           4 : }
     258             : 
     259             : template <typename T>
     260             : void
     261           6 : ColumnMajorMatrixTempl<T>::inverse(ColumnMajorMatrixTempl<T> & invA) const
     262             : {
     263           6 :   this->checkSquareness();
     264           6 :   this->checkShapeEquality(invA);
     265             : 
     266           6 :   PetscBLASInt n = _n_rows;
     267           6 :   PetscBLASInt return_value = 0;
     268             : 
     269           6 :   invA = *this;
     270             : 
     271           6 :   std::vector<PetscBLASInt> ipiv(n);
     272           6 :   T * invA_data = invA.rawData();
     273             : 
     274           6 :   PetscBLASInt buffer_size = n * 64;
     275           6 :   std::vector<T> buffer(buffer_size);
     276             : 
     277           6 :   LAPACKgetrf_(&n, &n, invA_data, &n, &ipiv[0], &return_value);
     278             : 
     279           6 :   LAPACKgetri_(&n, invA_data, &n, &ipiv[0], &buffer[0], &buffer_size, &return_value);
     280             : 
     281           6 :   if (return_value)
     282           0 :     mooseException("Error in LAPACK matrix-inverse calculation");
     283           6 : }
     284             : 
     285             : template <typename T>
     286             : void
     287          32 : ColumnMajorMatrixTempl<T>::checkSquareness() const
     288             : {
     289          32 :   if (_n_rows != _n_cols)
     290           6 :     mooseError("ColumnMajorMatrix error: Unable to perform the operation on a non-square matrix.");
     291          26 : }
     292             : 
     293             : template <typename T>
     294             : void
     295          20 : ColumnMajorMatrixTempl<T>::checkShapeEquality(const ColumnMajorMatrixTempl<T> & rhs) const
     296             : {
     297          20 :   if (_n_rows != rhs._n_rows || _n_cols != rhs._n_cols)
     298           4 :     mooseError("ColumnMajorMatrix error: Unable to perform the operation on matrices of different "
     299             :                "shapes.");
     300          16 : }
     301             : 
     302             : template <>
     303             : void
     304           0 : ColumnMajorMatrixTempl<ADReal>::inverse(ColumnMajorMatrixTempl<ADReal> &) const
     305             : {
     306           0 :   mooseError("Inverse solves with AD types is not supported for the ColumnMajorMatrix class.");
     307             : }
     308             : 
     309             : template <typename T>
     310             : inline ColumnMajorMatrixTempl<T>
     311           0 : ColumnMajorMatrixTempl<T>::abs()
     312             : {
     313             :   using std::abs;
     314           0 :   ColumnMajorMatrixTempl<T> & s = (*this);
     315             : 
     316           0 :   ColumnMajorMatrixTempl<T> ret_matrix(_n_rows, _n_cols);
     317             : 
     318           0 :   for (unsigned int j = 0; j < _n_cols; j++)
     319           0 :     for (unsigned int i = 0; i < _n_rows; i++)
     320           0 :       ret_matrix(i, j) = abs(s(i, j));
     321             : 
     322           0 :   return ret_matrix;
     323           0 : }
     324             : 
     325             : template <typename T>
     326             : inline T
     327           2 : ColumnMajorMatrixTempl<T>::norm()
     328             : {
     329             :   using std::sqrt;
     330           2 :   return sqrt(doubleContraction(*this));
     331             : }
     332             : 
     333             : template class ColumnMajorMatrixTempl<Real>;
     334             : template class ColumnMajorMatrixTempl<ADReal>;

Generated by: LCOV version 1.14