LCOV - code coverage report
Current view: top level - src/utils - ColumnMajorMatrix.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 126 167 75.4 %
Date: 2025-07-17 01:28:37 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         581 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(unsigned int rows, unsigned int cols)
      21         581 :   : _n_rows(rows), _n_cols(cols), _n_entries(rows * cols), _values(rows * cols, 0.0)
      22             : {
      23         581 :   _values.resize(rows * cols);
      24         581 : }
      25             : 
      26             : template <typename T>
      27         175 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(const ColumnMajorMatrixTempl<T> & rhs)
      28         175 :   : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
      29             : {
      30         175 :   *this = rhs;
      31         175 : }
      32             : 
      33             : template <typename T>
      34           1 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(const TypeTensor<T> & rhs)
      35           1 :   : _n_rows(LIBMESH_DIM),
      36           1 :     _n_cols(LIBMESH_DIM),
      37           1 :     _n_entries(LIBMESH_DIM * LIBMESH_DIM),
      38           1 :     _values(LIBMESH_DIM * LIBMESH_DIM)
      39             : {
      40           4 :   for (const auto j : make_range(Moose::dim))
      41          12 :     for (const auto i : make_range(Moose::dim))
      42           9 :       (*this)(i, j) = rhs(i, j);
      43           1 : }
      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           1 : ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(const TypeVector<T> & col1,
      61             :                                                   const TypeVector<T> & col2,
      62             :                                                   const TypeVector<T> & col3)
      63           1 :   : _n_rows(LIBMESH_DIM),
      64           1 :     _n_cols(LIBMESH_DIM),
      65           1 :     _n_entries(LIBMESH_DIM * LIBMESH_DIM),
      66           1 :     _values(LIBMESH_DIM * LIBMESH_DIM)
      67             : {
      68           1 :   unsigned int entry = 0;
      69           4 :   for (const auto i : make_range(Moose::dim))
      70           3 :     _values[entry++] = col1(i);
      71             : 
      72           4 :   for (const auto i : make_range(Moose::dim))
      73           3 :     _values[entry++] = col2(i);
      74             : 
      75           4 :   for (const auto i : make_range(Moose::dim))
      76           3 :     _values[entry++] = col3(i);
      77           1 : }
      78             : 
      79             : template <typename T>
      80             : ColumnMajorMatrixTempl<T>
      81           2 : ColumnMajorMatrixTempl<T>::kronecker(const ColumnMajorMatrixTempl<T> & rhs) const
      82             : {
      83           2 :   rhs.checkSquareness();
      84             : 
      85           1 :   ColumnMajorMatrixTempl<T> ret_matrix(_n_rows * rhs._n_rows, _n_cols * rhs._n_cols);
      86             : 
      87           3 :   for (unsigned int i = 0; i < _n_rows; i++)
      88           6 :     for (unsigned int j = 0; j < _n_cols; j++)
      89          12 :       for (unsigned int k = 0; k < rhs._n_rows; k++)
      90          24 :         for (unsigned int l = 0; l < rhs._n_cols; l++)
      91          16 :           ret_matrix(((i * _n_rows) + k), ((j * _n_cols) + l)) = (*this)(i, j) * rhs(k, l);
      92             : 
      93           1 :   return ret_matrix;
      94           0 : }
      95             : 
      96             : template <typename T>
      97             : ColumnMajorMatrixTempl<T> &
      98           1 : ColumnMajorMatrixTempl<T>::operator=(const DenseMatrix<T> & rhs)
      99             : {
     100           1 :   if (_n_rows != rhs.m() || _n_cols != rhs.n())
     101           1 :     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           1 : ColumnMajorMatrixTempl<T>::operator=(const DenseVector<T> & rhs)
     118             : {
     119           1 :   if (_n_rows != rhs.size() || _n_cols != 1)
     120           1 :     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           1 : ColumnMajorMatrixTempl<T>::eigen(ColumnMajorMatrixTempl<T> & eval,
     136             :                                  ColumnMajorMatrixTempl<T> & evec) const
     137             : {
     138           1 :   this->checkSquareness();
     139             : 
     140           1 :   char jobz = 'V';
     141           1 :   char uplo = 'U';
     142           1 :   PetscBLASInt n = _n_rows;
     143           1 :   PetscBLASInt return_value = 0;
     144             : 
     145           1 :   eval._n_rows = _n_rows;
     146           1 :   eval._n_cols = 1;
     147           1 :   eval._n_entries = _n_rows;
     148           1 :   eval._values.resize(_n_rows);
     149             : 
     150           1 :   evec = *this;
     151             : 
     152           1 :   T * eval_data = eval.rawData();
     153           1 :   T * evec_data = evec.rawData();
     154             : 
     155           1 :   PetscBLASInt buffer_size = n * 64;
     156           1 :   std::vector<T> buffer(buffer_size);
     157             : 
     158           1 :   LAPACKsyev_(&jobz, &uplo, &n, evec_data, &n, eval_data, &buffer[0], &buffer_size, &return_value);
     159             : 
     160           1 :   if (return_value)
     161           0 :     mooseError("error in lapack eigen solve");
     162           1 : }
     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           3 : 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           3 :   this->checkSquareness();
     180             : 
     181           3 :   ColumnMajorMatrixTempl<T> a(*this);
     182             : 
     183           3 :   char jobvl = 'V';
     184           3 :   char jobvr = 'V';
     185           3 :   PetscBLASInt n = _n_rows;
     186           3 :   PetscBLASInt return_value = 0;
     187             : 
     188           3 :   eval_real._n_rows = _n_rows;
     189           3 :   eval_real._n_cols = 1;
     190           3 :   eval_real._n_entries = _n_rows;
     191           3 :   eval_real._values.resize(_n_rows);
     192             : 
     193           3 :   eval_img._n_rows = _n_rows;
     194           3 :   eval_img._n_cols = 1;
     195           3 :   eval_img._n_entries = _n_rows;
     196           3 :   eval_img._values.resize(_n_rows);
     197             : 
     198           3 :   T * a_data = a.rawData();
     199           3 :   T * eval_r = eval_real.rawData();
     200           3 :   T * eval_i = eval_img.rawData();
     201           3 :   T * evec_ri = evec_right.rawData();
     202           3 :   T * evec_le = evec_left.rawData();
     203             : 
     204           3 :   PetscBLASInt buffer_size = n * 64;
     205           3 :   std::vector<T> buffer(buffer_size);
     206             : 
     207           3 :   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           3 :               &buffer[0],
     219             :               &buffer_size,
     220             :               &return_value);
     221             : 
     222           3 :   if (return_value)
     223           0 :     mooseError("error in lapack eigen solve");
     224           3 : }
     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           2 : ColumnMajorMatrixTempl<T>::exp(ColumnMajorMatrixTempl<T> & z) const
     239             : {
     240           2 :   this->checkSquareness();
     241             : 
     242           2 :   ColumnMajorMatrixTempl<T> a(*this);
     243           2 :   ColumnMajorMatrixTempl<T> evals_real(_n_rows, 1), evals_img(_n_rows, 1),
     244           2 :       evals_real2(_n_rows, _n_cols);
     245           2 :   ColumnMajorMatrixTempl<T> evec_right(_n_rows, _n_cols), evec_left(_n_rows, _n_cols);
     246           2 :   ColumnMajorMatrixTempl<T> evec_right_inverse(_n_rows, _n_cols);
     247             : 
     248           2 :   a.eigenNonsym(evals_real, evals_img, evec_right, evec_left);
     249             : 
     250           8 :   for (unsigned int i = 0; i < _n_rows; i++)
     251           6 :     evals_real2(i, i) = std::exp(evals_real(i, 0));
     252             : 
     253           2 :   evec_right.inverse(evec_right_inverse);
     254             : 
     255           2 :   z = evec_right * evals_real2 * evec_right_inverse;
     256           2 : }
     257             : 
     258             : template <typename T>
     259             : void
     260           3 : ColumnMajorMatrixTempl<T>::inverse(ColumnMajorMatrixTempl<T> & invA) const
     261             : {
     262           3 :   this->checkSquareness();
     263           3 :   this->checkShapeEquality(invA);
     264             : 
     265           3 :   PetscBLASInt n = _n_rows;
     266           3 :   PetscBLASInt return_value = 0;
     267             : 
     268           3 :   invA = *this;
     269             : 
     270           3 :   std::vector<PetscBLASInt> ipiv(n);
     271           3 :   T * invA_data = invA.rawData();
     272             : 
     273           3 :   PetscBLASInt buffer_size = n * 64;
     274           3 :   std::vector<T> buffer(buffer_size);
     275             : 
     276           3 :   LAPACKgetrf_(&n, &n, invA_data, &n, &ipiv[0], &return_value);
     277             : 
     278           3 :   LAPACKgetri_(&n, invA_data, &n, &ipiv[0], &buffer[0], &buffer_size, &return_value);
     279             : 
     280           3 :   if (return_value)
     281           0 :     mooseException("Error in LAPACK matrix-inverse calculation");
     282           3 : }
     283             : 
     284             : template <typename T>
     285             : void
     286          16 : ColumnMajorMatrixTempl<T>::checkSquareness() const
     287             : {
     288          16 :   if (_n_rows != _n_cols)
     289           3 :     mooseError("ColumnMajorMatrix error: Unable to perform the operation on a non-square matrix.");
     290          13 : }
     291             : 
     292             : template <typename T>
     293             : void
     294          10 : ColumnMajorMatrixTempl<T>::checkShapeEquality(const ColumnMajorMatrixTempl<T> & rhs) const
     295             : {
     296          10 :   if (_n_rows != rhs._n_rows || _n_cols != rhs._n_cols)
     297           2 :     mooseError("ColumnMajorMatrix error: Unable to perform the operation on matrices of different "
     298             :                "shapes.");
     299           8 : }
     300             : 
     301             : template <>
     302             : void
     303           0 : ColumnMajorMatrixTempl<ADReal>::inverse(ColumnMajorMatrixTempl<ADReal> &) const
     304             : {
     305           0 :   mooseError("Inverse solves with AD types is not supported for the ColumnMajorMatrix class.");
     306             : }
     307             : 
     308             : template <typename T>
     309             : inline ColumnMajorMatrixTempl<T>
     310           0 : ColumnMajorMatrixTempl<T>::abs()
     311             : {
     312           0 :   ColumnMajorMatrixTempl<T> & s = (*this);
     313             : 
     314           0 :   ColumnMajorMatrixTempl<T> ret_matrix(_n_rows, _n_cols);
     315             : 
     316           0 :   for (unsigned int j = 0; j < _n_cols; j++)
     317           0 :     for (unsigned int i = 0; i < _n_rows; i++)
     318           0 :       ret_matrix(i, j) = std::abs(s(i, j));
     319             : 
     320           0 :   return ret_matrix;
     321           0 : }
     322             : 
     323             : template <typename T>
     324             : inline T
     325           1 : ColumnMajorMatrixTempl<T>::norm()
     326             : {
     327           1 :   return std::sqrt(doubleContraction(*this));
     328             : }
     329             : 
     330             : template class ColumnMajorMatrixTempl<Real>;
     331             : template class ColumnMajorMatrixTempl<ADReal>;

Generated by: LCOV version 1.14