LCOV - code coverage report
Current view: top level - src/numerics - laspack_vector.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 109 183 59.6 %
Date: 2025-08-19 19:27:09 Functions: 19 32 59.4 %
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             : 
      19             : 
      20             : // C++ includes
      21             : #include <algorithm> // for std::min
      22             : #include <limits>
      23             : 
      24             : // Local Includes
      25             : #include "libmesh/dense_subvector.h"
      26             : #include "libmesh/dense_vector.h"
      27             : #include "libmesh/laspack_vector.h"
      28             : #include "libmesh/laspack_matrix.h"
      29             : #include "libmesh/int_range.h"
      30             : 
      31             : #ifdef LIBMESH_HAVE_LASPACK
      32             : 
      33             : namespace libMesh
      34             : {
      35             : 
      36             : template <typename T>
      37           8 : T LaspackVector<T>::sum () const
      38             : {
      39           4 :   libmesh_assert (this->closed());
      40             : 
      41           4 :   T _sum = 0;
      42             : 
      43           4 :   const numeric_index_type n = this->size();
      44             : 
      45          88 :   for (numeric_index_type i=0; i!=n; ++i)
      46          80 :     _sum += (*this)(i);
      47             : 
      48           8 :   return _sum;
      49             : }
      50             : 
      51             : 
      52             : 
      53             : template <typename T>
      54          40 : Real LaspackVector<T>::l1_norm () const
      55             : {
      56          20 :   libmesh_assert (this->closed());
      57             : 
      58          40 :   return static_cast<Real>(l1Norm_V(const_cast<QVector*>(&_vec)));
      59             : }
      60             : 
      61             : 
      62             : 
      63             : template <typename T>
      64          16 : Real LaspackVector<T>::l2_norm () const
      65             : {
      66           8 :   libmesh_assert (this->closed());
      67             : 
      68          16 :   return static_cast<Real>(l2Norm_V(const_cast<QVector*>(&_vec)));
      69             : }
      70             : 
      71             : 
      72             : 
      73             : template <typename T>
      74           8 : Real LaspackVector<T>::linfty_norm () const
      75             : {
      76           4 :   libmesh_assert (this->closed());
      77             : 
      78           8 :   return static_cast<Real>(MaxNorm_V(const_cast<QVector*>(&_vec)));
      79             : }
      80             : 
      81             : 
      82             : 
      83             : template <typename T>
      84           8 : NumericVector<T> & LaspackVector<T>::operator += (const NumericVector<T> & v)
      85             : {
      86           4 :   libmesh_assert (this->closed());
      87             : 
      88           8 :   this->add(1., v);
      89             : 
      90           8 :   return *this;
      91             : }
      92             : 
      93             : 
      94             : 
      95             : 
      96             : template <typename T>
      97          16 : NumericVector<T> & LaspackVector<T>::operator -= (const NumericVector<T> & v)
      98             : {
      99           8 :   libmesh_assert (this->closed());
     100             : 
     101          16 :   this->add(-1., v);
     102             : 
     103          16 :   return *this;
     104             : }
     105             : 
     106             : 
     107             : 
     108             : template <typename T>
     109           8 : NumericVector<T> & LaspackVector<T>::operator *= (const NumericVector<T> & v)
     110             : {
     111           4 :   libmesh_assert_equal_to(size(), v.size());
     112             : 
     113             : #ifndef NDEBUG
     114           4 :   const bool was_closed = this->_is_closed;
     115             : #endif
     116             : 
     117           4 :   const numeric_index_type n = this->size();
     118             : 
     119          88 :   for (numeric_index_type i=0; i<n; i++)
     120          80 :     this->set(i, (*this)(i) * v(i));
     121             : 
     122             :   // This is an embarrassingly parallel method, but set() isn't in
     123             :   // general so set() overzealously marked us as non-closed
     124             : #ifndef NDEBUG
     125           4 :   this->_is_closed = was_closed;
     126             : #endif
     127             : 
     128           8 :   return *this;
     129             : }
     130             : 
     131             : 
     132             : 
     133             : template <typename T>
     134           8 : NumericVector<T> & LaspackVector<T>::operator /= (const NumericVector<T> & v)
     135             : {
     136           4 :   libmesh_assert_equal_to(size(), v.size());
     137             : 
     138             : #ifndef NDEBUG
     139           4 :   const bool was_closed = this->_is_closed;
     140             : #endif
     141             : 
     142           4 :   const numeric_index_type n = this->size();
     143             : 
     144          88 :   for (numeric_index_type i=0; i<n; i++)
     145          80 :     this->set(i, (*this)(i) / v(i));
     146             : 
     147             :   // This is an embarrassingly parallel method, but set() isn't in
     148             :   // general so set() overzealously marked us as non-closed
     149             : #ifndef NDEBUG
     150           4 :   this->_is_closed = was_closed;
     151             : #endif
     152             : 
     153           8 :   return *this;
     154             : }
     155             : 
     156             : 
     157             : 
     158             : template <typename T>
     159           8 : void LaspackVector<T>::reciprocal()
     160             : {
     161           4 :   const numeric_index_type n = this->size();
     162             : 
     163             : #ifndef NDEBUG
     164           4 :   const bool was_closed = this->_is_closed;
     165             : #endif
     166             : 
     167          88 :   for (numeric_index_type i=0; i<n; i++)
     168             :     {
     169          40 :       T v = (*this)(i);
     170             : 
     171             :       // Don't divide by zero!
     172          40 :       libmesh_assert_not_equal_to (v, T(0));
     173             : 
     174          80 :       this->set(i, 1. / v);
     175             :     }
     176             : 
     177             :   // This is an embarrassingly parallel method, but set() isn't in
     178             :   // general so set() overzealously marked us as non-closed
     179             : #ifndef NDEBUG
     180           4 :   this->_is_closed = was_closed;
     181             : #endif
     182           8 : }
     183             : 
     184             : 
     185             : 
     186             : template <typename T>
     187           0 : void LaspackVector<T>::conjugate()
     188             : {
     189           0 :   const numeric_index_type n = this->size();
     190             : 
     191             : #ifndef NDEBUG
     192           0 :   const bool was_closed = this->_is_closed;
     193             : #endif
     194             : 
     195           0 :   for (numeric_index_type i=0; i<n; i++)
     196             :     {
     197           0 :       T v = (*this)(i);
     198             : 
     199           0 :       this->set(i, libmesh_conj(v) );
     200             :     }
     201             : 
     202             :   // This is an embarrassingly parallel method, but set() isn't in
     203             :   // general so set() overzealously marked us as non-closed
     204             : #ifndef NDEBUG
     205           0 :   this->_is_closed = was_closed;
     206             : #endif
     207           0 : }
     208             : 
     209             : 
     210             : template <typename T>
     211           8 : void LaspackVector<T>::add (const T v)
     212             : {
     213             : #ifndef NDEBUG
     214           4 :   const bool was_closed = this->_is_closed;
     215             : #endif
     216             : 
     217           4 :   const numeric_index_type n = this->size();
     218             : 
     219          88 :   for (numeric_index_type i=0; i<n; i++)
     220          80 :     this->add (i, v);
     221             : 
     222             :   // This is an embarrassingly parallel method, but set() isn't in
     223             :   // general so set() overzealously marked us as non-closed
     224             : #ifndef NDEBUG
     225           4 :   this->_is_closed = was_closed;
     226             : #endif
     227           8 : }
     228             : 
     229             : 
     230             : 
     231             : 
     232             : template <typename T>
     233           0 : void LaspackVector<T>::add (const NumericVector<T> & v)
     234             : {
     235           0 :   this->add (1., v);
     236           0 : }
     237             : 
     238             : 
     239             : 
     240             : template <typename T>
     241          32 : void LaspackVector<T>::add (const T a, const NumericVector<T> & v_in)
     242             : {
     243             :   // Make sure the vector passed in is really a LaspackVector
     244          16 :   const LaspackVector * v = cast_ptr<const LaspackVector *>(&v_in);
     245             : 
     246             : #ifndef NDEBUG
     247          16 :   const bool was_closed = this->_is_closed;
     248             : #endif
     249             : 
     250          16 :   libmesh_assert(v);
     251          16 :   libmesh_assert_equal_to (this->size(), v->size());
     252             : 
     253         352 :   for (auto i : make_range(v->size()))
     254         320 :     this->add (i, a*(*v)(i));
     255             : 
     256             : #ifndef NDEBUG
     257          16 :   this->_is_closed = was_closed;
     258             : #endif
     259          32 : }
     260             : 
     261             : 
     262             : 
     263             : template <typename T>
     264           0 : void LaspackVector<T>::add_vector (const NumericVector<T> & vec_in,
     265             :                                    const SparseMatrix<T> & mat_in)
     266             : {
     267             :   // Make sure the data passed in are really in Laspack types
     268           0 :   const LaspackVector<T> * vec = cast_ptr<const LaspackVector<T> *>(&vec_in);
     269           0 :   const LaspackMatrix<T> * mat = cast_ptr<const LaspackMatrix<T> *>(&mat_in);
     270             : 
     271           0 :   libmesh_assert(vec);
     272           0 :   libmesh_assert(mat);
     273             : 
     274             :   // += mat*vec
     275           0 :   AddAsgn_VV (&_vec, Mul_QV(const_cast<QMatrix*>(&mat->_QMat),
     276           0 :                             const_cast<QVector*>(&vec->_vec)));
     277           0 : }
     278             : 
     279             : 
     280             : template <typename T>
     281           0 : void LaspackVector<T>::add_vector_transpose (const NumericVector<T> &,
     282             :                                              const SparseMatrix<T> &)
     283             : {
     284           0 :   libmesh_not_implemented();
     285             : }
     286             : 
     287             : 
     288             : 
     289             : template <typename T>
     290           8 : void LaspackVector<T>::scale (const T factor)
     291             : {
     292           4 :   libmesh_assert (this->initialized());
     293             : 
     294           8 :   Asgn_VV(&_vec, Mul_SV (factor, &_vec));
     295           8 : }
     296             : 
     297             : template <typename T>
     298           0 : void LaspackVector<T>::abs()
     299             : {
     300           0 :   libmesh_assert (this->initialized());
     301             : 
     302           0 :   const numeric_index_type n = this->size();
     303             : 
     304           0 :   for (numeric_index_type i=0; i!=n; ++i)
     305           0 :     this->set(i,std::abs((*this)(i)));
     306           0 : }
     307             : 
     308             : template <typename T>
     309           8 : T LaspackVector<T>::dot (const NumericVector<T> & v_in) const
     310             : {
     311           4 :   libmesh_assert (this->initialized());
     312             : 
     313             :   // Make sure the NumericVector passed in is really a LaspackVector
     314           4 :   const LaspackVector<T> * v = cast_ptr<const LaspackVector<T> *>(&v_in);
     315           4 :   libmesh_assert(v);
     316             : 
     317          12 :   return Mul_VV (const_cast<QVector*>(&(this->_vec)),
     318          12 :                  const_cast<QVector*>(&(v->_vec)));
     319             : }
     320             : 
     321             : 
     322             : 
     323             : template <typename T>
     324             : NumericVector<T> &
     325           8 : LaspackVector<T>::operator = (const T s)
     326             : {
     327           4 :   libmesh_assert (this->initialized());
     328           4 :   libmesh_assert (this->closed());
     329             : 
     330           8 :   V_SetAllCmp (&_vec, s);
     331             : 
     332           8 :   return *this;
     333             : }
     334             : 
     335             : 
     336             : 
     337             : template <typename T>
     338             : NumericVector<T> &
     339          20 : LaspackVector<T>::operator = (const NumericVector<T> & v_in)
     340             : {
     341             :   // Make sure the NumericVector passed in is really a LaspackVector
     342          10 :   const LaspackVector<T> * v =
     343          10 :     cast_ptr<const LaspackVector<T> *>(&v_in);
     344             : 
     345          10 :   libmesh_assert(v);
     346             : 
     347          20 :   *this = *v;
     348             : 
     349          20 :   return *this;
     350             : }
     351             : 
     352             : 
     353             : 
     354             : template <typename T>
     355             : LaspackVector<T> &
     356          24 : LaspackVector<T>::operator = (const LaspackVector<T> & v)
     357             : {
     358          12 :   libmesh_assert (this->initialized());
     359          12 :   libmesh_assert (v.closed());
     360          12 :   libmesh_assert_equal_to (this->size(), v.size());
     361             : 
     362          24 :   if (v.size() != 0)
     363          24 :     Asgn_VV (const_cast<QVector*>(&_vec),
     364          12 :              const_cast<QVector*>(&v._vec)
     365             :              );
     366             : 
     367             : #ifndef NDEBUG
     368          12 :   this->_is_closed = true;
     369             : #endif
     370             : 
     371          24 :   return *this;
     372             : }
     373             : 
     374             : 
     375             : 
     376             : template <typename T>
     377             : NumericVector<T> &
     378           0 : LaspackVector<T>::operator = (const std::vector<T> & v)
     379             : {
     380             :   /**
     381             :    * Case 1:  The vector is the same size of
     382             :    * The global vector.  Only add the local components.
     383             :    */
     384           0 :   if (this->size() == v.size())
     385           0 :     for (auto i : index_range(v))
     386           0 :       this->set (i, v[i]);
     387             : 
     388             :   else
     389           0 :     libmesh_error_msg("this->size() = " << this->size() << " must be equal to v.size() = " << v.size());
     390             : 
     391           0 :   return *this;
     392             : }
     393             : 
     394             : 
     395             : template <typename T>
     396           0 : void LaspackVector<T>::localize (NumericVector<T> & v_local_in) const
     397             : {
     398             :   // Make sure the NumericVector passed in is really a LaspackVector
     399           0 :   LaspackVector<T> * v_local =
     400           0 :     cast_ptr<LaspackVector<T> *>(&v_local_in);
     401             : 
     402           0 :   libmesh_assert(v_local);
     403             : 
     404           0 :   *v_local = *this;
     405           0 : }
     406             : 
     407             : 
     408             : 
     409             : template <typename T>
     410           0 : void LaspackVector<T>::localize (NumericVector<T> & v_local_in,
     411             :                                  const std::vector<numeric_index_type> & libmesh_dbg_var(send_list)) const
     412             : {
     413             :   // Make sure the NumericVector passed in is really a LaspackVector
     414           0 :   LaspackVector<T> * v_local =
     415           0 :     cast_ptr<LaspackVector<T> *>(&v_local_in);
     416             : 
     417           0 :   libmesh_assert(v_local);
     418           0 :   libmesh_assert_less_equal (send_list.size(), v_local->size());
     419             : 
     420           0 :   *v_local = *this;
     421           0 : }
     422             : 
     423             : 
     424             : 
     425             : template <typename T>
     426           8 : void LaspackVector<T>::localize (std::vector<T> & v_local,
     427             :                                  const std::vector<numeric_index_type> & indices) const
     428             : {
     429             :   // LaspackVectors are serial, so we can just copy values
     430          12 :   v_local.resize(indices.size());
     431             : 
     432          88 :   for (auto i : index_range(v_local))
     433         120 :     v_local[i] = (*this)(indices[i]);
     434           8 : }
     435             : 
     436             : 
     437             : 
     438             : template <typename T>
     439           0 : void LaspackVector<T>::localize (const numeric_index_type libmesh_dbg_var(first_local_idx),
     440             :                                  const numeric_index_type libmesh_dbg_var(last_local_idx),
     441             :                                  const std::vector<numeric_index_type> & libmesh_dbg_var(send_list))
     442             : {
     443           0 :   libmesh_assert_equal_to (first_local_idx, 0);
     444           0 :   libmesh_assert_equal_to (last_local_idx+1, this->size());
     445             : 
     446           0 :   libmesh_assert_less_equal (send_list.size(), this->size());
     447             : 
     448             : #ifndef NDEBUG
     449           0 :   this->_is_closed = true;
     450             : #endif
     451           0 : }
     452             : 
     453             : 
     454             : 
     455             : template <typename T>
     456          32 : void LaspackVector<T>::localize (std::vector<T> & v_local) const
     457             : 
     458             : {
     459          32 :   v_local.resize(this->size());
     460             : 
     461         352 :   for (auto i : index_range(v_local))
     462         320 :     v_local[i] = (*this)(i);
     463          32 : }
     464             : 
     465             : 
     466             : 
     467             : template <typename T>
     468          16 : void LaspackVector<T>::localize_to_one (std::vector<T> & v_local,
     469             :                                         const processor_id_type libmesh_dbg_var(pid)) const
     470             : {
     471           8 :   libmesh_assert_equal_to (pid, 0);
     472             : 
     473          16 :   this->localize (v_local);
     474          16 : }
     475             : 
     476             : 
     477             : 
     478             : template <typename T>
     479           0 : void LaspackVector<T>::pointwise_mult (const NumericVector<T> & /*vec1*/,
     480             :                                        const NumericVector<T> & /*vec2*/)
     481             : {
     482           0 :   libmesh_not_implemented();
     483             : }
     484             : 
     485             : template <typename T>
     486           0 : void LaspackVector<T>::pointwise_divide (const NumericVector<T> & /*vec1*/,
     487             :                                          const NumericVector<T> & /*vec2*/)
     488             : {
     489           0 :   libmesh_not_implemented();
     490             : }
     491             : 
     492             : template <typename T>
     493           0 : Real LaspackVector<T>::max() const
     494             : {
     495           0 :   libmesh_assert (this->initialized());
     496           0 :   if (!this->size())
     497           0 :     return -std::numeric_limits<Real>::max();
     498             : 
     499           0 :   Real the_max = libmesh_real((*this)(0));
     500             : 
     501           0 :   const numeric_index_type n = this->size();
     502             : 
     503           0 :   for (numeric_index_type i=1; i<n; i++)
     504           0 :     the_max = std::max (the_max, libmesh_real((*this)(i)));
     505             : 
     506           0 :   return the_max;
     507             : }
     508             : 
     509             : 
     510             : 
     511             : template <typename T>
     512           0 : Real LaspackVector<T>::min () const
     513             : {
     514           0 :   libmesh_assert (this->initialized());
     515           0 :   if (!this->size())
     516           0 :     return std::numeric_limits<Real>::max();
     517             : 
     518           0 :   Real the_min = libmesh_real((*this)(0));
     519             : 
     520           0 :   const numeric_index_type n = this->size();
     521             : 
     522           0 :   for (numeric_index_type i=1; i<n; i++)
     523           0 :     the_min = std::min (the_min, libmesh_real((*this)(i)));
     524             : 
     525           0 :   return the_min;
     526             : }
     527             : 
     528             : 
     529             : //------------------------------------------------------------------
     530             : // Explicit instantiations
     531             : template class LIBMESH_EXPORT LaspackVector<Number>;
     532             : 
     533             : } // namespace libMesh
     534             : 
     535             : 
     536             : #endif // #ifdef LIBMESH_HAVE_LASPACK

Generated by: LCOV version 1.14