libMesh
eigen_sparse_vector.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2026 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 
21 #ifndef LIBMESH_EIGEN_SPARSE_VECTOR_H
22 #define LIBMESH_EIGEN_SPARSE_VECTOR_H
23 
24 
25 
26 #include "libmesh/libmesh_common.h"
27 
28 #ifdef LIBMESH_HAVE_EIGEN
29 
30 // Local includes
31 #include "libmesh/eigen_core_support.h"
32 #include "libmesh/numeric_vector.h"
33 
34 // C++ includes
35 #include <limits>
36 #include <mutex>
37 
38 namespace libMesh
39 {
40 
41 // Forward declarations
42 template <typename T> class EigenSparseMatrix;
43 template <typename T> class EigenSparseLinearSolver;
44 template <typename T> class SparseMatrix;
45 
54 template <typename T>
55 class EigenSparseVector final : public NumericVector<T>
56 {
57 public:
58 
62  explicit
63  EigenSparseVector (const Parallel::Communicator & comm_in,
64  const ParallelType = AUTOMATIC);
65 
69  explicit
70  EigenSparseVector (const Parallel::Communicator & comm_in,
71  const numeric_index_type n,
72  const ParallelType = AUTOMATIC);
73 
78  EigenSparseVector (const Parallel::Communicator & comm_in,
79  const numeric_index_type n,
80  const numeric_index_type n_local,
81  const ParallelType = AUTOMATIC);
82 
88  EigenSparseVector (const Parallel::Communicator & comm_in,
89  const numeric_index_type N,
90  const numeric_index_type n_local,
91  const std::vector<numeric_index_type> & ghost,
92  const ParallelType = AUTOMATIC);
93 
99  EigenSparseVector<T> & operator= (const EigenSparseVector<T> & v);
100 
105  EigenSparseVector (EigenSparseVector &&) = default;
106  EigenSparseVector (const EigenSparseVector &) = default;
108  virtual ~EigenSparseVector () = default;
109 
113  typedef EigenSV DataType;
114 
115  virtual void close () override;
116 
117  virtual void clear () override;
118 
119  virtual void zero () override;
120 
121  virtual std::unique_ptr<NumericVector<T>> zero_clone () const override;
122 
123  virtual std::unique_ptr<NumericVector<T>> clone () const override;
124 
125  virtual void init (const numeric_index_type N,
126  const numeric_index_type n_local,
127  const bool fast=false,
128  const ParallelType ptype=AUTOMATIC) override;
129 
130  virtual void init (const numeric_index_type N,
131  const bool fast=false,
132  const ParallelType ptype=AUTOMATIC) override;
133 
134  virtual void init (const numeric_index_type N,
135  const numeric_index_type n_local,
136  const std::vector<numeric_index_type> & ghost,
137  const bool fast = false,
138  const ParallelType = AUTOMATIC) override;
139 
140  virtual void init (const NumericVector<T> & other,
141  const bool fast = false) override;
142 
143  virtual NumericVector<T> & operator= (const T s) override;
144 
145  virtual NumericVector<T> & operator= (const NumericVector<T> & v) override;
146 
147  virtual NumericVector<T> & operator= (const std::vector<T> & v) override;
148 
149  virtual Real min () const override;
150 
151  virtual Real max () const override;
152 
153  virtual T sum () const override;
154 
155  virtual Real l1_norm () const override;
156 
157  virtual Real l2_norm () const override;
158 
159  virtual Real linfty_norm () const override;
160 
161  virtual numeric_index_type size () const override;
162 
163  virtual numeric_index_type local_size() const override;
164 
165  virtual numeric_index_type first_local_index() const override;
166 
167  virtual numeric_index_type last_local_index() const override;
168 
169  virtual T operator() (const numeric_index_type i) const override;
170 
171  virtual NumericVector<T> & operator += (const NumericVector<T> & v) override;
172 
173  virtual NumericVector<T> & operator -= (const NumericVector<T> & v) override;
174 
175  virtual NumericVector<T> & operator *= (const NumericVector<T> & v_in) override;
176 
177  virtual NumericVector<T> & operator /= (const NumericVector<T> & v_in) override;
178 
179  virtual void reciprocal() override;
180 
181  virtual void conjugate() override;
182 
183  virtual void set (const numeric_index_type i, const T value) override;
184 
185  virtual void add (const numeric_index_type i, const T value) override;
186 
187  virtual void add (const T s) override;
188 
189  virtual void add (const NumericVector<T> & v) override;
190 
191  virtual void add (const T a, const NumericVector<T> & v) override;
192 
198 
199  virtual void add_vector (const NumericVector<T> & v,
200  const SparseMatrix<T> & A) override;
201 
202  virtual void add_vector_transpose (const NumericVector<T> & v,
203  const SparseMatrix<T> & A) override;
204 
205  virtual void scale (const T factor) override;
206 
207  virtual void abs() override;
208 
209  virtual T dot(const NumericVector<T> & v) const override;
210 
211  virtual void localize (std::vector<T> & v_local) const override;
212 
213  virtual void localize (NumericVector<T> & v_local) const override;
214 
215  virtual void localize (NumericVector<T> & v_local,
216  const std::vector<numeric_index_type> & send_list) const override;
217 
218  virtual void localize (std::vector<T> & v_local,
219  const std::vector<numeric_index_type> & indices) const override;
220 
221  virtual void localize (const numeric_index_type first_local_idx,
222  const numeric_index_type last_local_idx,
223  const std::vector<numeric_index_type> & send_list) override;
224 
225  virtual void localize_to_one (std::vector<T> & v_local,
226  const processor_id_type proc_id=0) const override;
227 
228  virtual void pointwise_mult (const NumericVector<T> & vec1,
229  const NumericVector<T> & vec2) override;
230 
231  virtual void pointwise_divide (const NumericVector<T> & vec1,
232  const NumericVector<T> & vec2) override;
233 
234  virtual void create_subvector(NumericVector<T> & subvector,
235  const std::vector<numeric_index_type> & rows,
236  bool supplying_global_rows = true) const override;
237 
238  virtual void swap (NumericVector<T> & v) override;
239 
240  virtual std::size_t max_allowed_id() const override;
241 
242  virtual std::unique_ptr<NumericVector<T>>
243  get_subvector(const std::vector<numeric_index_type> & rows) override;
244 
245  virtual void restore_subvector(std::unique_ptr<NumericVector<T>> subvector,
246  const std::vector<numeric_index_type> & rows) override;
247 
253  DataType & vec () { return _vec; }
254  const DataType & vec () const { return _vec; }
255 
256 private:
257 
262 
266  friend class EigenSparseMatrix<T>;
267  friend class EigenSparseLinearSolver<T>;
268 };
269 
270 
271 
272 // ---------------------------------------------------------
273 // EigenSparseVector inline methods
274 template <typename T>
275 inline
277  const ParallelType ptype)
278  : NumericVector<T>(comm_in, ptype)
279 {
280  this->_type = ptype;
281 }
282 
283 
284 
285 template <typename T>
286 inline
288  const numeric_index_type n,
289  const ParallelType ptype)
290  : NumericVector<T>(comm_in, ptype)
291 {
292  this->init(n, n, false, ptype);
293 }
294 
295 
296 
297 template <typename T>
298 inline
300  const numeric_index_type n,
301  const numeric_index_type n_local,
302  const ParallelType ptype)
303  : NumericVector<T>(comm_in, ptype)
304 {
305  this->init(n, n_local, false, ptype);
306 }
307 
308 
309 
310 template <typename T>
311 inline
313  const numeric_index_type N,
314  const numeric_index_type n_local,
315  const std::vector<numeric_index_type> & ghost,
316  const ParallelType ptype)
317  : NumericVector<T>(comm_in, ptype)
318 {
319  this->init(N, n_local, ghost, false, ptype);
320 }
321 
322 
323 
324 template <typename T>
325 inline
327  const numeric_index_type n_local,
328  const bool fast,
329  const ParallelType)
330 {
331  // Eigen vectors only for serial cases,
332  // but can provide a "parallel" vector on one processor.
333  libmesh_error_msg_if(n != n_local, "Error: EigenSparseVectors can only be used in serial!");
334 
335  this->_type = SERIAL;
336 
337  // Clear initialized vectors
338  if (this->initialized())
339  this->clear();
340 
341  _vec.resize(n);
342 
343  this->_is_initialized = true;
344  this->_is_closed = true;
345 
346  // Optionally zero out all components
347  if (fast == false)
348  this->zero ();
349 
350  return;
351 }
352 
353 
354 
355 template <typename T>
356 inline
358  const bool fast,
359  const ParallelType ptype)
360 {
361  this->init(n,n,fast,ptype);
362 }
363 
364 
365 template <typename T>
366 inline
368  const numeric_index_type n_local,
369  const std::vector<numeric_index_type> & libmesh_dbg_var(ghost),
370  const bool fast,
371  const ParallelType ptype)
372 {
373  libmesh_assert(ghost.empty());
374  this->init(n,n_local,fast,ptype);
375 }
376 
377 
378 
379 /* Default implementation for solver packages for which ghosted
380  vectors are not yet implemented. */
381 template <class T>
383  const bool fast)
384 {
385  this->init(other.size(),other.local_size(),fast,other.type());
386 }
387 
388 
389 
390 template <typename T>
391 inline
393 {
394  libmesh_assert (this->initialized());
395 
396  this->_is_closed = true;
397 }
398 
399 
400 
401 template <typename T>
402 inline
404 {
405  _vec.resize(0);
406 
407  this->_is_initialized = false;
408  this->_is_closed = false;
409 }
410 
411 
412 
413 template <typename T> inline
415 {
416  libmesh_assert (this->initialized());
417  libmesh_assert (this->closed());
418 
419  _vec.setZero();
420 }
421 
422 
423 
424 template <typename T>
425 inline
426 std::unique_ptr<NumericVector<T>> EigenSparseVector<T>::zero_clone () const
427 {
428  std::unique_ptr<NumericVector<T>> cloned_vector =
429  std::make_unique<EigenSparseVector<T>>(this->comm());
430  cloned_vector->init(*this);
431  return cloned_vector;
432 }
433 
434 
435 
436 template <typename T>
437 inline
438 std::unique_ptr<NumericVector<T>> EigenSparseVector<T>::clone () const
439 {
440  std::unique_ptr<NumericVector<T>> cloned_vector =
441  std::make_unique<EigenSparseVector<T>>(this->comm());
442  cloned_vector->init(*this, true);
443  *cloned_vector = *this;
444  return cloned_vector;
445 }
446 
447 
448 
449 template <typename T>
450 inline
452 {
453  libmesh_assert (this->initialized());
454 
455  return static_cast<numeric_index_type>(_vec.size());
456 }
457 
458 
459 
460 template <typename T>
461 inline
463 {
464  libmesh_assert (this->initialized());
465 
466  return this->size();
467 }
468 
469 
470 
471 template <typename T>
472 inline
474 {
475  libmesh_assert (this->initialized());
476 
477  return 0;
478 }
479 
480 
481 
482 template <typename T>
483 inline
485 {
486  libmesh_assert (this->initialized());
487 
488  return this->size();
489 }
490 
491 
492 
493 template <typename T>
494 inline
496 {
497  libmesh_assert (this->initialized());
498  libmesh_assert_less (i, this->size());
499 
500  std::scoped_lock lock(this->_numeric_vector_mutex);
501  _vec[static_cast<eigen_idx_type>(i)] = value;
502 
503  this->_is_closed = false;
504 }
505 
506 
507 
508 template <typename T>
509 inline
511 {
512  libmesh_assert (this->initialized());
513  libmesh_assert_less (i, this->size());
514 
515  std::scoped_lock lock(this->_numeric_vector_mutex);
516  _vec[static_cast<eigen_idx_type>(i)] += value;
517 
518  this->_is_closed = false;
519 }
520 
521 
522 
523 template <typename T>
524 inline
526 {
527  libmesh_assert (this->initialized());
528  libmesh_assert ( ((i >= this->first_local_index()) &&
529  (i < this->last_local_index())) );
530 
531  return _vec[static_cast<eigen_idx_type>(i)];
532 }
533 
534 
535 
536 template <typename T>
537 inline
539 {
540  EigenSparseVector<T> & v = cast_ref<EigenSparseVector<T> &>(other);
541 
542  _vec.swap(v._vec);
543 
544  std::swap (this->_is_closed, v._is_closed);
545  std::swap (this->_is_initialized, v._is_initialized);
546  std::swap (this->_type, v._type);
547 }
548 
549 
550 
551 template <typename T>
552 inline
554 {
555  // We use the Eigen::Matrix type which appears to be templated on
556  // int for its sizes, see e.g. https://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html
557  return std::numeric_limits<int>::max();
558 }
559 
560 } // namespace libMesh
561 
562 
563 #endif // #ifdef LIBMESH_HAVE_EIGEN
564 #endif // LIBMESH_EIGEN_SPARSE_VECTOR_H
virtual std::size_t max_allowed_id() const override
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:331
The EigenSparseMatrix class wraps a sparse matrix object from the Eigen library.
virtual Real linfty_norm() const override
virtual void localize(std::vector< T > &v_local) const override
Creates a copy of the global vector in the local vector v_local.
virtual void conjugate() override
Negates the imaginary component of each entry in the vector.
virtual void pointwise_divide(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
virtual T sum() const override
virtual void add_vector(const NumericVector< T > &v, const SparseMatrix< T > &A) override
Computes , i.e.
DataType _vec
Actual Eigen::SparseVector<> we are wrapping.
virtual std::unique_ptr< NumericVector< T > > get_subvector(const std::vector< numeric_index_type > &rows) override
Creates a view into this vector using the indices in rows.
virtual void reciprocal() override
Computes the component-wise reciprocal, .
virtual numeric_index_type size() const =0
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
Subtracts v from *this, .
virtual Real min() const override
This class provides an interface to Eigen iterative solvers that is compatible with the libMesh Linea...
virtual std::unique_ptr< NumericVector< T > > clone() const override
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
virtual numeric_index_type last_local_index() const override
int32_t eigen_idx_type
The libMesh namespace provides an interface to certain functionality in the library.
const Number zero
.
Definition: libmesh.h:297
virtual void close() override
Calls the NumericVector&#39;s internal assembly routines, ensuring that the values are consistent across ...
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
uint8_t processor_id_type
Definition: id_types.h:104
Generic sparse matrix.
Definition: vector_fe_ex5.C:46
EigenSV DataType
Convenient typedefs.
virtual Real l2_norm() const override
dof_id_type numeric_index_type
Definition: id_types.h:99
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:305
virtual void clear() override
Restores the NumericVector<T> to a pristine state.
virtual Real max() const override
virtual NumericVector< T > & operator/=(const NumericVector< T > &v_in) override
Computes the component-wise division of this vector&#39;s entries by another&#39;s, .
Eigen::Matrix< Number, Eigen::Dynamic, 1 > EigenSV
virtual numeric_index_type size() const override
const DataType & vec() const
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
virtual numeric_index_type local_size() const override
EigenSparseVector< T > & operator=(const EigenSparseVector< T > &v)
Copy assignment operator.
libmesh_assert(ctx)
virtual void init(const numeric_index_type N, const numeric_index_type n_local, const bool fast=false, const ParallelType ptype=AUTOMATIC) override
Change the dimension of the vector to n.
virtual NumericVector< T > & operator*=(const NumericVector< T > &v_in) override
Computes the component-wise multiplication of this vector&#39;s entries by another&#39;s, ...
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A) override
Computes , i.e.
virtual void abs() override
Sets for each entry in the vector.
virtual void create_subvector(NumericVector< T > &subvector, const std::vector< numeric_index_type > &rows, bool supplying_global_rows=true) const override
Fills in subvector from this vector using the indices in rows.
DataType & vec()
References to the underlying Eigen data types.
virtual void localize_to_one(std::vector< T > &v_local, const processor_id_type proc_id=0) const override
Creates a local copy of the global vector in v_local only on processor proc_id.
ParallelType _type
Type of vector.
virtual void set(const numeric_index_type i, const T value) override
Sets v(i) = value.
virtual void scale(const T factor) override
Scale each element of the vector by the given factor.
virtual numeric_index_type first_local_index() const override
ParallelType type() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual Real l1_norm() const override
virtual void add(const numeric_index_type i, const T value) override
Adds value to the vector entry specified by i.
virtual numeric_index_type local_size() const =0
static const bool value
Definition: xdr_io.C:55
virtual void zero() override
Set all entries to zero.
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:324
EigenSparseVector(const Parallel::Communicator &comm_in, const ParallelType=AUTOMATIC)
Dummy-Constructor.
virtual void restore_subvector(std::unique_ptr< NumericVector< T >> subvector, const std::vector< numeric_index_type > &rows) override
Restores a view into this vector using the indices in rows.
virtual T operator()(const numeric_index_type i) const override
virtual ~EigenSparseVector()=default
virtual T dot(const NumericVector< T > &v) const override
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
Adds v to *this, .
This class provides a nice interface to the Eigen C++-based data structures for serial vectors...
ParallelType
Defines an enum for parallel data structure types.