LCOV - code coverage report
Current view: top level - src/numerics - diagonal_matrix.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 93 118 78.8 %
Date: 2025-08-19 19:27:09 Functions: 60 76 78.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : #include "libmesh/diagonal_matrix.h"
      19             : #include "libmesh/numeric_vector.h"
      20             : #include "libmesh/dense_matrix.h"
      21             : #include "libmesh/dof_map.h"
      22             : #include "libmesh/libmesh_common.h"
      23             : 
      24             : 
      25             : // C++ Includes
      26             : #include <memory>
      27             : 
      28             : 
      29             : namespace libMesh
      30             : {
      31             : 
      32             : template <typename T>
      33         639 : DiagonalMatrix<T>::DiagonalMatrix(const Parallel::Communicator & comm_in) : SparseMatrix<T>(comm_in)
      34             : {
      35        1242 :   _diagonal = NumericVector<T>::build(comm_in);
      36         639 : }
      37             : 
      38             : template <typename T>
      39             : DiagonalMatrix<T> &
      40           4 : DiagonalMatrix<T>::operator=(const NumericVector<T> & vec)
      41             : {
      42          71 :   *_diagonal = vec;
      43           4 :   return *this;
      44             : }
      45             : 
      46             : template <typename T>
      47             : DiagonalMatrix<T> &
      48          75 : DiagonalMatrix<T>::operator=(NumericVector<T> && vec)
      49             : {
      50             :   // Don't get confused by the &&: vec is an lvalue reference; the && just
      51             :   // indicates that we are receiving an object that is safe to move from. Note
      52             :   // that we are not going to use std::move here because we do not have
      53             :   // (virtual) move assignment operations defined for NumericVector sub-classes
      54         142 :   _diagonal->swap(vec);
      55          75 :   return *this;
      56             : }
      57             : 
      58             : template <typename T>
      59             : void
      60         284 : DiagonalMatrix<T>::init(const numeric_index_type m,
      61             :                         const numeric_index_type /*n*/,
      62             :                         const numeric_index_type m_l,
      63             :                         const numeric_index_type /*n_l*/,
      64             :                         const numeric_index_type /*nnz*/,
      65             :                         const numeric_index_type /*noz*/,
      66             :                         const numeric_index_type /*blocksize*/)
      67             : {
      68         284 :   _diagonal->init(m, m_l);
      69         284 : }
      70             : 
      71             : template <typename T>
      72             : void
      73           0 : DiagonalMatrix<T>::init(const ParallelType type)
      74             : {
      75           0 :   libmesh_assert(this->_dof_map);
      76             : 
      77           0 :   _diagonal->init(this->_dof_map->n_dofs(),
      78           0 :                   this->_dof_map->n_local_dofs(),
      79             :                   /*fast=*/false,
      80             :                   type);
      81           0 : }
      82             : 
      83             : template <typename T>
      84             : void
      85         213 : DiagonalMatrix<T>::init(const NumericVector<T> & other, const bool fast)
      86             : {
      87         213 :   _diagonal->init(other, fast);
      88         213 : }
      89             : 
      90             : template <typename T>
      91             : void
      92         213 : DiagonalMatrix<T>::init(const DiagonalMatrix<T> & other, const bool fast)
      93             : {
      94         213 :   init(other.diagonal(), fast);
      95         213 : }
      96             : 
      97             : template <typename T>
      98             : void
      99           0 : DiagonalMatrix<T>::clear()
     100             : {
     101           0 :   _diagonal->clear();
     102           0 : }
     103             : 
     104             : template <typename T>
     105             : void
     106         213 : DiagonalMatrix<T>::zero()
     107             : {
     108         213 :   _diagonal->zero();
     109         213 : }
     110             : 
     111             : template <typename T>
     112          71 : std::unique_ptr<SparseMatrix<T>> DiagonalMatrix<T>::zero_clone () const
     113             : {
     114             :   // Make empty copy with matching comm
     115          73 :   auto mat_copy = std::make_unique<DiagonalMatrix<T>>(this->comm());
     116             : 
     117             :   // Initialize copy with our same nonzero structure, and explicitly
     118             :   // zero values using fast == false.
     119          71 :   mat_copy->init(*this, /*fast=*/false);
     120             : 
     121          73 :   return mat_copy;
     122          67 : }
     123             : 
     124             : 
     125             : 
     126             : template <typename T>
     127          71 : std::unique_ptr<SparseMatrix<T>> DiagonalMatrix<T>::clone () const
     128             : {
     129             :   // Make empty copy with matching comm
     130          73 :   auto mat_copy = std::make_unique<DiagonalMatrix<T>>(this->comm());
     131             : 
     132             :   // Make copy of our diagonal
     133          73 :   auto diag_copy = _diagonal->clone();
     134             : 
     135             :   // Swap diag_copy with diagonal in mat_copy
     136           4 :   *mat_copy = std::move(*diag_copy);
     137             : 
     138          73 :   return mat_copy;
     139          67 : }
     140             : 
     141             : template <typename T>
     142             : void
     143         426 : DiagonalMatrix<T>::close()
     144             : {
     145         426 :   _diagonal->close();
     146         426 : }
     147             : 
     148             : template <typename T>
     149             : numeric_index_type
     150         657 : DiagonalMatrix<T>::m() const
     151             : {
     152         639 :   return _diagonal->size();
     153             : }
     154             : 
     155             : template <typename T>
     156             : numeric_index_type
     157         639 : DiagonalMatrix<T>::n() const
     158             : {
     159         639 :   return _diagonal->size();
     160             : }
     161             : 
     162             : template <typename T>
     163             : numeric_index_type
     164        1491 : DiagonalMatrix<T>::row_start() const
     165             : {
     166        1491 :   return _diagonal->first_local_index();
     167             : }
     168             : 
     169             : template <typename T>
     170             : numeric_index_type
     171        1491 : DiagonalMatrix<T>::row_stop() const
     172             : {
     173        1491 :   return _diagonal->last_local_index();
     174             : }
     175             : 
     176             : template <typename T>
     177             : numeric_index_type
     178           0 : DiagonalMatrix<T>::col_start() const
     179             : {
     180           0 :   return _diagonal->first_local_index();
     181             : }
     182             : 
     183             : template <typename T>
     184             : numeric_index_type
     185           0 : DiagonalMatrix<T>::col_stop() const
     186             : {
     187           0 :   return _diagonal->last_local_index();
     188             : }
     189             : 
     190             : template <typename T>
     191             : void
     192         524 : DiagonalMatrix<T>::set(const numeric_index_type i, const numeric_index_type j, const T value)
     193             : {
     194         524 :   if (i == j)
     195         453 :     _diagonal->set(i, value);
     196         524 : }
     197             : 
     198             : template <typename T>
     199             : void
     200         595 : DiagonalMatrix<T>::add(const numeric_index_type i, const numeric_index_type j, const T value)
     201             : {
     202         595 :   if (i == j)
     203         524 :     _diagonal->add(i, value);
     204         595 : }
     205             : 
     206             : template <typename T>
     207             : void
     208          71 : DiagonalMatrix<T>::add_matrix(const DenseMatrix<T> & dm,
     209             :                               const std::vector<numeric_index_type> & rows,
     210             :                               const std::vector<numeric_index_type> & cols)
     211             : {
     212           4 :   auto m = dm.m();
     213           4 :   auto n = dm.n();
     214             : 
     215         524 :   for (decltype(m) i = 0; i < m; ++i)
     216        4364 :     for (decltype(n) j = 0; j < n; ++j)
     217             :     {
     218        3911 :       auto global_i = rows[i];
     219        3911 :       auto global_j = cols[j];
     220        3911 :       if (global_i == global_j)
     221         458 :         _diagonal->add(global_i, dm(i, j));
     222             :     }
     223          71 : }
     224             : 
     225             : template <typename T>
     226             : void
     227          71 : DiagonalMatrix<T>::add_matrix(const DenseMatrix<T> & dm,
     228             :                               const std::vector<numeric_index_type> & dof_indices)
     229             : {
     230          71 :   _diagonal->add_vector(dm.diagonal(), dof_indices);
     231          71 : }
     232             : 
     233             : template <typename T>
     234             : void
     235          71 : DiagonalMatrix<T>::add(const T a, const SparseMatrix<T> & X)
     236             : {
     237          73 :   auto x_diagonal = _diagonal->zero_clone();
     238          73 :   X.get_diagonal(*x_diagonal);
     239          73 :   _diagonal->add(a, *x_diagonal);
     240          71 : }
     241             : 
     242             : template <typename T>
     243             : T
     244       22904 : DiagonalMatrix<T>::operator()(const numeric_index_type i, const numeric_index_type j) const
     245             : {
     246       22904 :   if (i == j)
     247        5460 :     return (*_diagonal)(i);
     248             :   else
     249          68 :     return 0;
     250             : }
     251             : 
     252             : template <typename T>
     253             : Real
     254         284 : DiagonalMatrix<T>::l1_norm() const
     255             : {
     256         284 :   return _diagonal->l1_norm();
     257             : }
     258             : 
     259             : template <typename T>
     260             : Real
     261          71 : DiagonalMatrix<T>::linfty_norm() const
     262             : {
     263          71 :   return _diagonal->linfty_norm();
     264             : }
     265             : 
     266             : template <typename T>
     267             : bool
     268         284 : DiagonalMatrix<T>::closed() const
     269             : {
     270         284 :   return _diagonal->closed();
     271             : }
     272             : 
     273             : template <typename T>
     274             : void
     275           0 : DiagonalMatrix<T>::print_personal(std::ostream & os) const
     276             : {
     277           0 :   _diagonal->print(os);
     278           0 : }
     279             : 
     280             : 
     281             : 
     282             : template <typename T>
     283             : void
     284         142 : DiagonalMatrix<T>::get_diagonal(NumericVector<T> & dest) const
     285             : {
     286         146 :   dest = *_diagonal;
     287         142 : }
     288             : 
     289             : 
     290             : 
     291             : template <typename T>
     292             : void
     293          71 : DiagonalMatrix<T>::get_transpose(SparseMatrix<T> & dest) const
     294             : {
     295          71 :   auto diagonal_dest = dynamic_cast<DiagonalMatrix<T> *>(&dest);
     296          71 :   if (diagonal_dest)
     297           4 :     *diagonal_dest = *_diagonal;
     298             :   else
     299           0 :     libmesh_error_msg("DenseMatrix<T>::get_transpose currently only accepts another DenseMatrix<T> "
     300             :                       "as its argument");
     301          71 : }
     302             : 
     303             : 
     304             : 
     305             : template <typename T>
     306             : void
     307           0 : DiagonalMatrix<T>::get_row(numeric_index_type i,
     308             :                            std::vector<numeric_index_type> & indices,
     309             :                            std::vector<T> & values) const
     310             : {
     311           0 :   indices.clear();
     312           0 :   indices.push_back(i);
     313           0 :   values.clear();
     314           0 :   values.push_back((*_diagonal)(i));
     315           0 : }
     316             : 
     317             : 
     318             : 
     319             : template <typename T>
     320             : void
     321          71 : DiagonalMatrix<T>::zero_rows(std::vector<numeric_index_type> & rows, T val/*=0*/)
     322             : {
     323         524 :   for (auto row : rows)
     324         453 :     _diagonal->set(row, val);
     325          71 : }
     326             : 
     327             : template <typename T>
     328             : const NumericVector<T> &
     329          83 : DiagonalMatrix<T>::diagonal() const
     330             : {
     331          83 :   return *_diagonal;
     332             : }
     333             : 
     334             : template <typename T>
     335             : void
     336           0 : DiagonalMatrix<T>::restore_original_nonzero_pattern()
     337             : {
     338           0 :   _diagonal->zero();
     339           0 : }
     340             : 
     341             : template class LIBMESH_EXPORT DiagonalMatrix<Number>;
     342             : }

Generated by: LCOV version 1.14