Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
dense_vector.h
Go to the documentation of this file.
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 #ifndef LIBMESH_DENSE_VECTOR_H
21 #define LIBMESH_DENSE_VECTOR_H
22 
23 // Local Includes
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/dense_vector_base.h"
26 #include "libmesh/compare_types.h"
27 #include "libmesh/int_range.h"
28 #include "libmesh/tensor_tools.h"
29 
30 #ifdef LIBMESH_HAVE_EIGEN
31 #include "libmesh/ignore_warnings.h"
32 #include <Eigen/Core>
33 #include "libmesh/restore_warnings.h"
34 #endif
35 
36 #ifdef LIBMESH_HAVE_METAPHYSICL
37 #include "metaphysicl/raw_type.h"
38 #endif
39 
40 // C++ includes
41 #include <vector>
42 #include <initializer_list>
43 
44 namespace libMesh
45 {
46 
57 template<typename T>
58 class DenseVector : public DenseVectorBase<T>
59 {
60 public:
61 
65  explicit
66  DenseVector(const unsigned int n=0);
67 
72  explicit
73  DenseVector(const unsigned int n,
74  const T & val);
75 
79  template <typename T2>
80  DenseVector (const DenseVector<T2> & other_vector);
81 
85  template <typename T2>
86  DenseVector (const std::vector<T2> & other_vector);
87 
91  template <typename T2>
92  DenseVector (std::initializer_list<T2> init_list);
93 
98  DenseVector (DenseVector &&) = default;
99  DenseVector (const DenseVector &) = default;
100  DenseVector & operator= (const DenseVector &) = default;
101  DenseVector & operator= (DenseVector &&) = default;
102  virtual ~DenseVector() = default;
103 
104  virtual unsigned int size() const override final
105  {
106  return cast_int<unsigned int>(_val.size());
107  }
108 
109  virtual bool empty() const override final
110  { return _val.empty(); }
111 
112  virtual void zero() override final;
113 
117  const T & operator() (const unsigned int i) const;
118 
122  T & operator() (const unsigned int i);
123 
127  const T & operator[] (const unsigned int i) const { return (*this)(i); }
128 
132  T & operator[] (const unsigned int i) { return (*this)(i); }
133 
134  virtual T el(const unsigned int i) const override final
135  { return (*this)(i); }
136 
137  virtual T & el(const unsigned int i) override final
138  { return (*this)(i); }
139 
145  template <typename T2>
146  DenseVector<T> & operator = (const DenseVector<T2> & other_vector);
147 
151  void swap(DenseVector<T> & other_vector);
152 
156  void resize (const unsigned int n);
157 
162  template <typename T2>
163  void append (const DenseVector<T2> & other_vector);
164 
168  void scale (const T factor);
169 
175  DenseVector<T> & operator*= (const T factor);
176 
184  template <typename T2, typename T3>
185  typename boostcopy::enable_if_c<
186  ScalarTraits<T2>::value, void >::type
187  add (const T2 factor,
188  const DenseVector<T3> & vec);
189 
195  template <typename T2>
196  typename CompareTypes<T, T2>::supertype dot (const DenseVector<T2> & vec) const;
197 
204  template <typename T2>
206 
210  template <typename T2>
211  bool operator== (const DenseVector<T2> & vec) const;
212 
216  template <typename T2>
217  bool operator!= (const DenseVector<T2> & vec) const;
218 
224  template <typename T2>
226 
232  template <typename T2>
234 
239  Real min () const;
240 
245  Real max () const;
246 
251  Real l1_norm () const;
252 
257  Real l2_norm () const;
258 
263  Real linfty_norm () const;
264 
269  void get_principal_subvector (unsigned int sub_n, DenseVector<T> & dest) const;
270 
278  std::vector<T> & get_values() { return _val; }
279 
283  const std::vector<T> & get_values() const { return _val; }
284 
288  typename std::vector<T>::const_iterator begin() const { return _val.begin(); }
289  typename std::vector<T>::iterator begin() { return _val.begin(); }
290 
294  typename std::vector<T>::const_iterator end() const { return _val.end(); }
295  typename std::vector<T>::iterator end() { return _val.end(); }
296 
297 private:
298 
302  std::vector<T> _val;
303 };
304 
305 
306 
307 // ------------------------------------------------------------
308 // DenseVector member functions
309 template<typename T>
310 inline
311 DenseVector<T>::DenseVector(const unsigned int n) :
312  _val (n, T{})
313 {
314 }
315 
316 
317 template<typename T>
318 inline
319 DenseVector<T>::DenseVector(const unsigned int n,
320  const T & val) :
321  _val (n, val)
322 {
323 }
324 
325 
326 
327 template<typename T>
328 template<typename T2>
329 inline
331  DenseVectorBase<T>()
332 {
333  const std::vector<T2> & other_vals = other_vector.get_values();
334 
335  _val.clear();
336 
337  const int N = cast_int<int>(other_vals.size());
338  _val.reserve(N);
339 
340  for (int i=0; i<N; i++)
341  _val.push_back(other_vals[i]);
342 }
343 
344 
345 
346 template<typename T>
347 template<typename T2>
348 inline
349 DenseVector<T>::DenseVector (const std::vector<T2> & other_vector) :
350  _val(other_vector)
351 {
352 }
353 
354 
355 template<typename T>
356 template <typename T2>
357 inline
358 DenseVector<T>::DenseVector (std::initializer_list<T2> init_list) :
359  _val(init_list.begin(), init_list.end())
360 {
361 }
362 
363 
364 
365 template<typename T>
366 template<typename T2>
367 inline
369 {
370  const std::vector<T2> & other_vals = other_vector.get_values();
371 
372  _val.clear();
373 
374  const int N = cast_int<int>(other_vals.size());
375  _val.reserve(N);
376 
377  for (int i=0; i<N; i++)
378  _val.push_back(other_vals[i]);
379 
380  return *this;
381 }
382 
383 
384 
385 template<typename T>
386 inline
388 {
389  _val.swap(other_vector._val);
390 }
391 
392 
393 
394 template<typename T>
395 inline
396 void DenseVector<T>::resize(const unsigned int n)
397 {
398  _val.resize(n);
399 
400  zero();
401 }
402 
403 
404 
405 template<typename T>
406 template<typename T2>
407 inline
408 void DenseVector<T>::append (const DenseVector<T2> & other_vector)
409 {
410  const std::vector<T2> & other_vals = other_vector.get_values();
411 
412  _val.reserve(this->size() + other_vals.size());
413  _val.insert(_val.end(), other_vals.begin(), other_vals.end());
414 }
415 
416 
417 
418 template<typename T>
419 inline
421 {
422  std::fill (_val.begin(),
423  _val.end(),
424  T{});
425 }
426 
427 
428 
429 template<typename T>
430 inline
431 const T & DenseVector<T>::operator () (const unsigned int i) const
432 {
433  libmesh_assert_less (i, _val.size());
434 
435  return _val[i];
436 }
437 
438 
439 
440 template<typename T>
441 inline
442 T & DenseVector<T>::operator () (const unsigned int i)
443 {
444  libmesh_assert_less (i, _val.size());
445 
446  return _val[i];
447 }
448 
449 
450 
451 template<typename T>
452 inline
453 void DenseVector<T>::scale (const T factor)
454 {
455  const int N = cast_int<int>(_val.size());
456  for (int i=0; i<N; i++)
457  _val[i] *= factor;
458 }
459 
460 
461 
462 template<typename T>
463 inline
465 {
466  this->scale(factor);
467  return *this;
468 }
469 
470 
471 
472 template<typename T>
473 template<typename T2, typename T3>
474 inline
475 typename boostcopy::enable_if_c<
476  ScalarTraits<T2>::value, void >::type
477 DenseVector<T>::add (const T2 factor,
478  const DenseVector<T3> & vec)
479 {
480  libmesh_assert_equal_to (this->size(), vec.size());
481 
482  const int N = cast_int<int>(_val.size());
483  for (int i=0; i<N; i++)
484  (*this)(i) += static_cast<T>(factor)*vec(i);
485 }
486 
487 
488 
489 template<typename T>
490 template<typename T2>
491 inline
493 {
494  if (!_val.size())
495  return 0.;
496 
497  libmesh_assert_equal_to (this->size(), vec.size());
498 
499 #ifdef LIBMESH_HAVE_EIGEN
500  // We reverse the order of the arguments to dot() here since
501  // the convention in Eigen is to take the complex conjugate of the
502  // *first* argument, while ours is to take the complex conjugate of
503  // the second.
504  return Eigen::Map<const typename Eigen::Matrix<T2, Eigen::Dynamic, 1>>(vec.get_values().data(), vec.size())
505  .dot(Eigen::Map<const typename Eigen::Matrix<T, Eigen::Dynamic, 1>>(_val.data(), _val.size()));
506 #else
507  typename CompareTypes<T, T2>::supertype val = 0.;
508 
509  const int N = cast_int<int>(_val.size());
510  // The following pragma tells clang's vectorizer that it is safe to
511  // reorder floating point operations for this loop.
512 #ifdef __clang__
513 #pragma clang loop vectorize(enable)
514 #endif
515  for (int i=0; i<N; i++)
516  val += (*this)(i)*libmesh_conj(vec(i));
517 
518  return val;
519 #endif
520 }
521 
522 template<typename T>
523 template<typename T2>
524 inline
526 {
527  libmesh_assert_equal_to (this->size(), vec.size());
528 
529  typename CompareTypes<T, T2>::supertype val = 0.;
530 
531  const int N = cast_int<int>(_val.size());
532  for (int i=0; i<N; i++)
533  val += (*this)(i)*(vec(i));
534 
535  return val;
536 }
537 
538 template<typename T>
539 template<typename T2>
540 inline
542 {
543  libmesh_assert_equal_to (this->size(), vec.size());
544 
545  const int N = cast_int<int>(_val.size());
546  for (int i=0; i<N; i++)
547  if ((*this)(i) != vec(i))
548  return false;
549 
550  return true;
551 }
552 
553 
554 
555 template<typename T>
556 template<typename T2>
557 inline
559 {
560  libmesh_assert_equal_to (this->size(), vec.size());
561 
562  const int N = cast_int<int>(_val.size());
563  for (int i=0; i<N; i++)
564  if ((*this)(i) != vec(i))
565  return true;
566 
567  return false;
568 }
569 
570 
571 
572 template<typename T>
573 template<typename T2>
574 inline
576 {
577  libmesh_assert_equal_to (this->size(), vec.size());
578 
579  const int N = cast_int<int>(_val.size());
580  for (int i=0; i<N; i++)
581  (*this)(i) += vec(i);
582 
583  return *this;
584 }
585 
586 
587 
588 template<typename T>
589 template<typename T2>
590 inline
592 {
593  libmesh_assert_equal_to (this->size(), vec.size());
594 
595  const int N = cast_int<int>(_val.size());
596  for (int i=0; i<N; i++)
597  (*this)(i) -= vec(i);
598 
599  return *this;
600 }
601 
602 
603 
604 template<typename T>
605 inline
607 {
608  libmesh_assert (this->size());
609  Real my_min = libmesh_real((*this)(0));
610 
611  const int N = cast_int<int>(_val.size());
612  for (int i=1; i!=N; i++)
613  {
614  Real current = libmesh_real((*this)(i));
615  my_min = (my_min < current? my_min : current);
616  }
617  return my_min;
618 }
619 
620 
621 
622 template<typename T>
623 inline
625 {
626  libmesh_assert (this->size());
627  Real my_max = libmesh_real((*this)(0));
628 
629  const int N = cast_int<int>(_val.size());
630  for (int i=1; i!=N; i++)
631  {
632  Real current = libmesh_real((*this)(i));
633  my_max = (my_max > current? my_max : current);
634  }
635  return my_max;
636 }
637 
638 
639 
640 template<typename T>
641 inline
643 {
644  if (!_val.size())
645  return 0.;
646 
647 #ifdef LIBMESH_HAVE_EIGEN
648  return Eigen::Map<const typename Eigen::Matrix<T, Eigen::Dynamic, 1>>(_val.data(), _val.size()).template lpNorm<1>();
649 #else
650  Real my_norm = 0.;
651  const int N = cast_int<int>(_val.size());
652  for (int i=0; i!=N; i++)
653  my_norm += std::abs((*this)(i));
654 
655  return my_norm;
656 #endif
657 }
658 
659 
660 
661 template<typename T>
662 inline
664 {
665  if (!_val.size())
666  return 0.;
667 
668 #ifdef LIBMESH_HAVE_EIGEN
669  return Eigen::Map<const typename Eigen::Matrix<T, Eigen::Dynamic, 1>>(_val.data(), _val.size()).norm();
670 #else
671  Real my_norm = 0.;
672  const int N = cast_int<int>(_val.size());
673  // The following pragma tells clang's vectorizer that it is safe to
674  // reorder floating point operations for this loop.
675 #ifdef __clang__
676 #pragma clang loop vectorize(enable)
677 #endif
678  for (int i=0; i!=N; i++)
679  my_norm += TensorTools::norm_sq((*this)(i));
680 
681  return sqrt(my_norm);
682 #endif
683 }
684 
685 
686 
687 template<typename T>
688 inline
690 {
691  if (!_val.size())
692  return 0.;
693 
694 #ifdef LIBMESH_HAVE_EIGEN
695  return Eigen::Map<const typename Eigen::Matrix<T, Eigen::Dynamic, 1>>(_val.data(), _val.size()).template lpNorm<Eigen::Infinity>();
696 #else
697  Real my_norm = TensorTools::norm_sq((*this)(0));
698 
699  const int N = cast_int<int>(_val.size());
700  for (int i=1; i!=N; i++)
701  {
702  Real current = TensorTools::norm_sq((*this)(i));
703  my_norm = (my_norm > current? my_norm : current);
704  }
705  return sqrt(my_norm);
706 #endif
707 }
708 
709 
710 
711 template<typename T>
712 inline
714  DenseVector<T> & dest) const
715 {
716  libmesh_assert_less_equal ( sub_n, this->size() );
717 
718  dest.resize(sub_n);
719  const int N = cast_int<int>(sub_n);
720  for (int i=0; i<N; i++)
721  dest(i) = _val[i];
722 }
723 
724 } // namespace libMesh
725 
726 #ifdef LIBMESH_HAVE_METAPHYSICL
727 namespace MetaPhysicL
728 {
729 template <typename T>
730 struct RawType<libMesh::DenseVector<T>>
731 {
733 
735  {
736  const auto s = in.size();
737  value_type ret(s);
738  for (unsigned int i = 0; i < s; ++i)
739  ret(i) = raw_value(in(i));
740 
741  return ret;
742  }
743 };
744 }
745 #endif
746 
747 #endif // LIBMESH_DENSE_VECTOR_H
T libmesh_real(T a)
DenseVector< T > & operator*=(const T factor)
Multiplies every element in the vector by factor.
Definition: dense_vector.h:464
boostcopy::enable_if_c< ScalarTraits< T2 >::value, void >::type add(const T2 factor, const DenseVector< T3 > &vec)
Adds factor times vec to this vector.
Definition: dense_vector.h:477
virtual void zero() override final
Set every element in the vector to 0.
Definition: dense_vector.h:420
T libmesh_conj(T a)
void scale(MeshBase &mesh, const Real xs, const Real ys=0., const Real zs=0.)
Scales the mesh.
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:396
std::vector< T > & get_values()
Definition: dense_vector.h:278
bool operator==(const DenseVector< T2 > &vec) const
Definition: dense_vector.h:541
static value_type value(const libMesh::DenseVector< T > &in)
Definition: dense_vector.h:734
The libMesh namespace provides an interface to certain functionality in the library.
const Number zero
.
Definition: libmesh.h:304
void scale(const T factor)
Multiplies every element in the vector by factor.
Definition: dense_vector.h:453
bool operator==(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &y)
void get_principal_subvector(unsigned int sub_n, DenseVector< T > &dest) const
Puts the principal subvector of size sub_n (i.e.
Definition: dense_vector.h:713
const std::vector< T > & get_values() const
Definition: dense_vector.h:283
void swap(DenseVector< T > &other_vector)
STL-like swap method.
Definition: dense_vector.h:387
Order & operator-=(Order &o, T p)
Definition: enum_order.h:118
virtual T & el(const unsigned int i) override final
Definition: dense_vector.h:137
DenseVector & operator=(const DenseVector &)=default
Real linfty_norm() const
Definition: dense_vector.h:689
std::vector< T >::const_iterator begin() const
Definition: dense_vector.h:288
std::vector< T >::const_iterator end() const
Definition: dense_vector.h:294
auto l1_norm(const NumericVector< T > &vec)
Real l2_norm() const
Definition: dense_vector.h:663
libMesh::DenseVector< typename RawType< T >::value_type > value_type
Definition: dense_vector.h:732
virtual ~DenseVector()=default
virtual bool empty() const override final
Definition: dense_vector.h:109
libmesh_assert(ctx)
bool operator!=(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &y)
std::vector< T >::iterator begin()
Definition: dense_vector.h:289
std::vector< T > _val
The actual data values, stored as a 1D array.
Definition: dense_vector.h:302
auto norm(const T &a) -> decltype(std::abs(a))
Definition: tensor_tools.h:74
bool operator!=(const DenseVector< T2 > &vec) const
Definition: dense_vector.h:558
CompareTypes< T, T2 >::supertype indefinite_dot(const DenseVector< T2 > &vec) const
Definition: dense_vector.h:525
CompareTypes< T, T2 >::supertype dot(const DenseVector< T2 > &vec) const
Definition: dense_vector.h:492
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
auto norm_sq(const T &a) -> decltype(std::norm(a))
Definition: tensor_tools.h:104
Real l1_norm() const
Definition: dense_vector.h:642
DenseVector(const unsigned int n=0)
Constructor.
Definition: dense_vector.h:311
void append(const DenseVector< T2 > &other_vector)
Append additional entries to (resizing, but unchanging) the vector.
Definition: dense_vector.h:408
virtual unsigned int size() const override final
Definition: dense_vector.h:104
virtual T el(const unsigned int i) const override final
Definition: dense_vector.h:134
Defines an abstract dense vector base class for use in Finite Element-type computations.
Definition: dof_map.h:72
Defines a dense vector for use in Finite Element-type computations.
Definition: dof_map.h:73
const T & operator[](const unsigned int i) const
Definition: dense_vector.h:127
DenseVector< T > & operator+=(const DenseVector< T2 > &vec)
Adds vec to this vector.
Definition: dense_vector.h:575
std::vector< T >::iterator end()
Definition: dense_vector.h:295
DenseVector< T > & operator-=(const DenseVector< T2 > &vec)
Subtracts vec from this vector.
Definition: dense_vector.h:591
Order & operator+=(Order &o, T p)
Definition: enum_order.h:111