MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
vector.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_VECTOR
13#define MFEM_VECTOR
14
15#include "../general/array.hpp"
16#ifdef MFEM_USE_ADIOS2
18#endif
21#include "../general/device.hpp"
22
23#include <cmath>
24#include <cstdlib>
25#include <iostream>
26#include <limits>
27#include <type_traits>
28#include <initializer_list>
29#if defined(_MSC_VER) && (_MSC_VER < 1800)
30#include <float.h>
31#define isfinite _finite
32#endif
33
34#ifdef MFEM_USE_MPI
35#include <mpi.h>
36#endif
37
38namespace mfem
39{
40
41/** Count the number of entries in an array of doubles for which isfinite
42 is false, i.e. the entry is a NaN or +/-Inf. */
43inline int CheckFinite(const real_t *v, const int n);
44
45/// Define a shortcut for std::numeric_limits<double>::infinity()
46#ifndef __CYGWIN__
47inline constexpr real_t infinity()
48{
49 return std::numeric_limits<real_t>::infinity();
50}
51#else
52// On Cygwin math.h defines a function 'infinity()' which will conflict with the
53// above definition if we have 'using namespace mfem;' and try to use something
54// like 'double a = infinity();'. This 'infinity()' function is non-standard and
55// is defined by the Newlib C standard library implementation used by Cygwin,
56// see https://en.wikipedia.org/wiki/Newlib, http://www.sourceware.org/newlib.
57using ::infinity;
58#endif
59
60/// Generate a random `real_t` number in the interval [0,1) using rand().
62{
63 constexpr real_t max = (real_t)(RAND_MAX) + 1_r;
64#if defined(MFEM_USE_SINGLE)
65 // Note: For RAND_MAX = 2^31-1, float(RAND_MAX) = 2^31, and
66 // max = float(RAND_MAX)+1.0f is equal to 2^31 too; this is the actual value
67 // that we want for max. However, this rounding behavior means that for a
68 // range of values of rand() close to RAND_MAX, the expression
69 // float(rand())/max will give 1.0f.
70 //
71 // Therefore, to ensure we return a number less than 1, we take the minimum
72 // of float(rand())/max and (1 - 2^(-24)), where the latter number is the
73 // largest float less than 1.
74 return std::fmin(real_t(rand())/max, 0.9999999403953552_r);
75#else
76 return real_t(rand())/max;
77#endif
78}
79
80/// Vector data type.
81class Vector
82{
83protected:
84
86 int size;
87
88public:
89
90 /** Default constructor for Vector. Sets size = 0, and calls Memory::Reset on
91 data through Memory<double>'s default constructor. */
92 Vector(): size(0) { }
93
94 /// Copy constructor. Allocates a new data array and copies the data.
95 Vector(const Vector &);
96
97 /// Move constructor. "Steals" data from its argument.
98 Vector(Vector&& v);
99
100 /// @brief Creates vector of size s.
101 /// @warning Entries are not initialized to zero!
102 explicit Vector(int s);
103
104 /// Creates a vector referencing an array of doubles, owned by someone else.
105 /** The pointer @a data_ can be NULL. The data array can be replaced later
106 with SetData(). */
107 Vector(real_t *data_, int size_)
108 { data.Wrap(data_, size_, false); size = size_; }
109
110 /** @brief Create a Vector referencing a sub-vector of the Vector @a base
111 starting at the given offset, @a base_offset, and size @a size_. */
112 Vector(Vector &base, int base_offset, int size_)
113 : data(base.data, base_offset, size_), size(size_) { }
114
115 /// Create a Vector of size @a size_ using MemoryType @a mt.
116 Vector(int size_, MemoryType mt)
117 : data(size_, mt), size(size_) { }
118
119 /** @brief Create a Vector of size @a size_ using host MemoryType @a h_mt and
120 device MemoryType @a d_mt. */
121 Vector(int size_, MemoryType h_mt, MemoryType d_mt)
122 : data(size_, h_mt, d_mt), size(size_) { }
123
124 /// Create a vector from a statically sized C-style array of convertible type
125 template <typename CT, int N>
126 explicit Vector(const CT (&values)[N]) : Vector(N)
127 { std::copy(values, values + N, begin()); }
128
129 /// Create a vector using a braced initializer list
130 template <typename CT, typename std::enable_if<
131 std::is_convertible<CT,real_t>::value,bool>::type = true>
132 explicit Vector(std::initializer_list<CT> values) :
133 Vector(static_cast<int> (values.size()))
134 { std::copy(values.begin(), values.end(), begin()); }
135
136 /// Enable execution of Vector operations using the mfem::Device.
137 /** The default is to use Backend::CPU (serial execution on each MPI rank),
138 regardless of the mfem::Device configuration.
139
140 When appropriate, MFEM functions and class methods will enable the use
141 of the mfem::Device for their Vector parameters.
142
143 Some derived classes, e.g. GridFunction, enable the use of the
144 mfem::Device by default. */
145 virtual void UseDevice(bool use_dev) const { data.UseDevice(use_dev); }
146
147 /// Return the device flag of the Memory object used by the Vector
148 virtual bool UseDevice() const { return data.UseDevice(); }
149
150 /// Reads a vector from multiple files
151 void Load(std::istream ** in, int np, int * dim);
152
153 /// Load a vector from an input stream.
154 void Load(std::istream &in, int Size);
155
156 /// Load a vector from an input stream, reading the size from the stream.
157 void Load(std::istream &in) { int s; in >> s; Load(in, s); }
158
159 /// @brief Resize the vector to size @a s.
160 /** If the new size is less than or equal to Capacity() then the internal
161 data array remains the same. Otherwise, the old array is deleted, if
162 owned, and a new array of size @a s is allocated without copying the
163 previous content of the Vector.
164 @warning In the second case above (new size greater than current one),
165 the vector will allocate new data array, even if it did not own the
166 original data! Also, new entries are not initialized! */
167 void SetSize(int s);
168
169 /// Resize the vector to size @a s using MemoryType @a mt.
170 void SetSize(int s, MemoryType mt);
171
172 /// Resize the vector to size @a s using the MemoryType of @a v.
173 void SetSize(int s, const Vector &v) { SetSize(s, v.GetMemory().GetMemoryType()); }
174
175 /// Update \ref Capacity() to @a res (if less than current), keeping existing entries.
176 void Reserve(int res);
177
178 /// Delete entries at @a indices and resize vector accordingly.
179 /// @warning Indices must be unique!
180 void DeleteAt(const Array<int> &indices);
181
182 /// Set the Vector data.
183 /// @warning This method should be called only when OwnsData() is false.
184 void SetData(real_t *d) { data.Wrap(d, data.Capacity(), false); }
185
186 /// Set the Vector data and size.
187 /** The Vector does not assume ownership of the new data. The new size is
188 also used as the new Capacity().
189 @warning This method should be called only when OwnsData() is false.
190 @sa NewDataAndSize(). */
191 void SetDataAndSize(real_t *d, int s) { data.Wrap(d, s, false); size = s; }
192
193 /// Set the Vector data and size, deleting the old data, if owned.
194 /** The Vector does not assume ownership of the new data. The new size is
195 also used as the new Capacity().
196 @sa SetDataAndSize(). */
197 void NewDataAndSize(real_t *d, int s)
198 {
199 data.Delete();
200 SetDataAndSize(d, s);
201 }
202
203 /// Reset the Vector to use the given external Memory @a mem and size @a s.
204 /** If @a own_mem is false, the Vector will not own any of the pointers of
205 @a mem.
206
207 Note that when @a own_mem is true, the @a mem object can be destroyed
208 immediately by the caller but `mem.Delete()` should NOT be called since
209 the Vector object takes ownership of all pointers owned by @a mem.
210
211 @sa NewDataAndSize(). */
212 inline void NewMemoryAndSize(const Memory<real_t> &mem, int s, bool own_mem);
213
214 /// Reset the Vector to be a reference to a sub-vector of @a base.
215 inline void MakeRef(Vector &base, int offset, int size);
216
217 /** @brief Reset the Vector to be a reference to a sub-vector of @a base
218 without changing its current size. */
219 inline void MakeRef(Vector &base, int offset);
220
221 /// Set the Vector data (host pointer) ownership flag.
222 void MakeDataOwner() const { data.SetHostPtrOwner(true); }
223
224 /// Destroy a vector
225 void Destroy();
226
227 /** @brief Delete the device pointer, if owned. If @a copy_to_host is true
228 and the data is valid only on device, move it to host before deleting.
229 Invalidates the device memory. */
230 void DeleteDevice(bool copy_to_host = true)
231 { data.DeleteDevice(copy_to_host); }
232
233 /// Returns the size of the vector.
234 inline int Size() const { return size; }
235
236 /// Return the size of the currently allocated data array.
237 /** It is always true that Capacity() >= Size(). */
238 inline int Capacity() const { return data.Capacity(); }
239
240 /// Return a pointer to the beginning of the Vector data.
241 /** @warning This method should be used with caution as it gives write access
242 to the data of const-qualified Vector%s. */
243 inline real_t *GetData() const
244 { return const_cast<real_t*>((const real_t*)data); }
245
246 /// Conversion to `double *`. Deprecated.
247 MFEM_DEPRECATED inline operator real_t *() { return data; }
248
249 /// Conversion to `const double *`. Deprecated.
250 MFEM_DEPRECATED inline operator const real_t *() const { return data; }
251
252 /// STL-like begin.
253 inline real_t *begin() { return data; }
254
255 /// STL-like end.
256 inline real_t *end() { return data + size; }
257
258 /// STL-like begin (const version).
259 inline const real_t *begin() const { return data; }
260
261 /// STL-like end (const version).
262 inline const real_t *end() const { return data + size; }
263
264 /// Return a reference to the Memory object used by the Vector.
266
267 /** @brief Return a reference to the Memory object used by the Vector, const
268 version. */
269 const Memory<real_t> &GetMemory() const { return data; }
270
271 /// Update the memory location of the vector to match @a v.
272 void SyncMemory(const Vector &v) const { GetMemory().Sync(v.GetMemory()); }
273
274 /// Update the alias memory location of the vector to match @a v.
275 void SyncAliasMemory(const Vector &v) const
276 { GetMemory().SyncAlias(v.GetMemory(),Size()); }
277
278 /// Read the Vector data (host pointer) ownership flag.
279 inline bool OwnsData() const { return data.OwnsHostPtr(); }
280
281 /// Changes the ownership of the data; after the call the Vector is empty
282 inline void StealData(real_t **p)
283 { *p = data; data.Reset(); size = 0; }
284
285 /// Changes the ownership of the data; after the call the Vector is empty
286 inline real_t *StealData() { real_t *p; StealData(&p); return p; }
287
288 /// Access Vector entries. Index i = 0 .. size-1.
289 real_t &Elem(int i);
290
291 /// Read only access to Vector entries. Index i = 0 .. size-1.
292 const real_t &Elem(int i) const;
293
294 /// Access Vector entries using () for 0-based indexing.
295 /** @note If MFEM_DEBUG is enabled, bounds checking is performed. */
296 inline real_t &operator()(int i);
297
298 /// Read only access to Vector entries using () for 0-based indexing.
299 /** @note If MFEM_DEBUG is enabled, bounds checking is performed. */
300 inline const real_t &operator()(int i) const;
301
302 /// Access Vector entries using [] for 0-based indexing.
303 /** @note If MFEM_DEBUG is enabled, bounds checking is performed. */
304 inline real_t &operator[](int i) { return (*this)(i); }
305
306 /// Read only access to Vector entries using [] for 0-based indexing.
307 /** @note If MFEM_DEBUG is enabled, bounds checking is performed. */
308 inline const real_t &operator[](int i) const { return (*this)(i); }
309
310 /// Dot product with a `double *` array.
311 /// This function always executes on the CPU. A HostRead() will be called if
312 /// required.
313 /// To optionally execute on the device:
314 /// Vector tmp(v, Size());
315 /// res = (*this) * tmp;
316 real_t operator*(const real_t *v) const;
317
318 /// Return the inner-product.
319 real_t operator*(const Vector &v) const;
320
321 /// Copy Size() entries from @a v.
322 Vector &operator=(const real_t *v);
323
324 /// Copy assignment.
325 /** @note Defining this method overwrites the implicitly defined copy
326 assignment operator. */
327 Vector &operator=(const Vector &v);
328
329 /// Move assignment
330 Vector &operator=(Vector&& v);
331
332 /// Redefine '=' for vector = constant.
333 Vector &operator=(real_t value);
334
336
337 /// Component-wise scaling: (*this)(i) *= v(i)
338 Vector &operator*=(const Vector &v);
339
341
342 /// Component-wise division: (*this)(i) /= v(i)
343 Vector &operator/=(const Vector &v);
344
346
347 Vector &operator-=(const Vector &v);
348
350
351 Vector &operator+=(const Vector &v);
352
353 /// (*this) += a * Va
354 Vector &Add(const real_t a, const Vector &Va);
355
356 /// (*this) = a * x
357 Vector &Set(const real_t a, const Vector &x);
358
359 /// (*this)[i + offset] = v[i]
360 void SetVector(const Vector &v, int offset);
361
362 /// (*this)[i + offset] += v[i]
363 void AddSubVector(const Vector &v, int offset);
364
365 /// (*this) = -(*this)
366 void Neg();
367
368 /// (*this)(i) = 1.0 / (*this)(i)
369 void Reciprocal();
370
371 /// (*this)(i) = abs((*this)(i))
372 void Abs();
373
374 /// (*this)(i) = pow((*this)(i), p)
375 void Pow(const real_t p);
376
377 /// Swap the contents of two Vectors
378 /** Implemented without using move assignment, avoiding Destroy() calls. */
379 inline void Swap(Vector &other);
380
381 /// Set v = v1 + v2.
382 friend void add(const Vector &v1, const Vector &v2, Vector &v);
383
384 /// Set v = v1 + alpha * v2.
385 friend void add(const Vector &v1, real_t alpha, const Vector &v2, Vector &v);
386
387 /// z = a * (x + y)
388 friend void add(const real_t a, const Vector &x, const Vector &y, Vector &z);
389
390 /// z = a * x + b * y
391 friend void add(const real_t a, const Vector &x,
392 const real_t b, const Vector &y, Vector &z);
393
394 /// Set v = v1 - v2.
395 friend void subtract(const Vector &v1, const Vector &v2, Vector &v);
396
397 /// z = a * (x - y)
398 friend void subtract(const real_t a, const Vector &x,
399 const Vector &y, Vector &z);
400
401 /// Computes cross product of this vector with another 3D vector.
402 /// vout = this x vin.
403 void cross3D(const Vector &vin, Vector &vout) const;
404
405 /// v = median(v,lo,hi) entrywise. Implementation assumes lo <= hi.
406 void median(const Vector &lo, const Vector &hi);
407
408 /// Extract entries listed in @a dofs to the output Vector @a elemvect.
409 /** Negative dof values cause the -dof-1 position in @a elemvect to receive
410 the -val in from this Vector. */
411 void GetSubVector(const Array<int> &dofs, Vector &elemvect) const;
412
413 /// Extract entries listed in @a dofs to the output array @a elem_data.
414 /** Negative dof values cause the -dof-1 position in @a elem_data to receive
415 the -val in from this Vector. */
416 void GetSubVector(const Array<int> &dofs, real_t *elem_data) const;
417
418 /// Set the entries listed in @a dofs to the given @a value.
419 /** Negative dof values cause the -dof-1 position in this Vector to receive
420 the -value. */
421 void SetSubVector(const Array<int> &dofs, const real_t value);
422
423 /// Set the entries listed in @a dofs to the given @a value (always on host).
424 /** Negative dof values cause the -dof-1 position in this Vector to receive
425 the -value.
426
427 As opposed to SetSubVector(const Array<int>&, const real_t), this
428 function will execute only on host, even if the vector or the @a dofs
429 array have the device flag set. */
430 void SetSubVectorHost(const Array<int> &dofs, const real_t value);
431
432 /** @brief Set the entries listed in @a dofs to the values given in the @a
433 elemvect Vector. Negative dof values cause the -dof-1 position in this
434 Vector to receive the -val from @a elemvect. */
435 void SetSubVector(const Array<int> &dofs, const Vector &elemvect);
436
437 /** @brief Set the entries listed in @a dofs to the values given the @a ,
438 elem_data array. Negative dof values cause the -dof-1 position in this
439 Vector to receive the -val from @a elem_data. */
440 void SetSubVector(const Array<int> &dofs, real_t *elem_data);
441
442 /** @brief Add elements of the @a elemvect Vector to the entries listed in @a
443 dofs. Negative dof values cause the -dof-1 position in this Vector to add
444 the -val from @a elemvect. */
445 void AddElementVector(const Array<int> & dofs, const Vector & elemvect);
446
447 /** @brief Add elements of the @a elem_data array to the entries listed in @a
448 dofs. Negative dof values cause the -dof-1 position in this Vector to add
449 the -val from @a elem_data. */
450 void AddElementVector(const Array<int> & dofs, real_t *elem_data);
451
452 /** @brief Add @a times the elements of the @a elemvect Vector to the entries
453 listed in @a dofs. Negative dof values cause the -dof-1 position in this
454 Vector to add the -a*val from @a elemvect. */
455 void AddElementVector(const Array<int> & dofs, const real_t a,
456 const Vector & elemvect);
457
458 /// Set all vector entries NOT in the @a dofs Array to the given @a val.
459 void SetSubVectorComplement(const Array<int> &dofs, const real_t val);
460
461 /// Prints vector to stream out.
462 void Print(std::ostream &out = mfem::out, int width = 8) const;
463
464#ifdef MFEM_USE_ADIOS2
465 /// Prints vector to stream out.
466 /// @param out adios2stream output
467 /// @param variable_name variable name associated with current Vector
468 void Print(adios2stream & out, const std::string& variable_name) const;
469#endif
470
471 /// Prints vector to stream out in HYPRE_Vector format.
472 void Print_HYPRE(std::ostream &out) const;
473
474 /// Prints vector as a List for importing into Mathematica.
475 /** The resulting file can be read into Mathematica using an expression such
476 as: myVec = Get["output_file_name"]
477 The Mathematica variable "myVec" will then be assigned to a new
478 List object containing the data from this MFEM Vector. */
479 void PrintMathematica(std::ostream &out = mfem::out) const;
480
481 /// Print the Vector size and hash of its data.
482 /** This is a compact text representation of the Vector contents that can be
483 used to compare vectors from different runs without the need to save the
484 whole vector. */
485 void PrintHash(std::ostream &out) const;
486
487 /// Set random values in the vector.
488 void Randomize(int seed = 0);
489 /// Returns the l2 norm of the vector.
490 real_t Norml2() const;
491 /// Returns the l_infinity norm of the vector.
492 real_t Normlinf() const;
493 /// Returns the l_1 norm of the vector.
494 real_t Norml1() const;
495 /// Returns the l_p norm of the vector.
496 real_t Normlp(real_t p) const;
497 /// Returns the maximal element of the vector.
498 real_t Max() const;
499 /// Returns the minimal element of the vector.
500 real_t Min() const;
501 /// Return the sum of the vector entries
502 real_t Sum() const;
503 /// Compute the square of the Euclidean distance to another vector.
504 inline real_t DistanceSquaredTo(const real_t *p) const;
505 /// Compute the square of the Euclidean distance to another vector.
506 inline real_t DistanceSquaredTo(const Vector &p) const;
507 /// Compute the Euclidean distance to another vector.
508 inline real_t DistanceTo(const real_t *p) const;
509 /// Compute the Euclidean distance to another vector.
510 inline real_t DistanceTo(const Vector &p) const;
511
512 /** @brief Count the number of entries in the Vector for which isfinite
513 is false, i.e. the entry is a NaN or +/-Inf. */
514 int CheckFinite() const { return mfem::CheckFinite(HostRead(), size); }
515
516 /// Destroys vector.
517 virtual ~Vector();
518
519 /// Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
520 virtual const real_t *Read(bool on_dev = true) const
521 { return mfem::Read(data, size, on_dev); }
522
523 /// Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
524 virtual const real_t *HostRead() const
525 { return mfem::Read(data, size, false); }
526
527 /// Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
528 virtual real_t *Write(bool on_dev = true)
529 { return mfem::Write(data, size, on_dev); }
530
531 /// Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
532 virtual real_t *HostWrite()
533 { return mfem::Write(data, size, false); }
534
535 /// Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
536 virtual real_t *ReadWrite(bool on_dev = true)
537 { return mfem::ReadWrite(data, size, on_dev); }
538
539 /// Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
541 { return mfem::ReadWrite(data, size, false); }
542
543 /** @brief Create a mutable (non-const) view of the Vector as Array<real_t>
544 that can be used to pass Vector objects to functions that take Array
545 arguments.
546
547 The returned MemoryView object is implicitly and explicitly convertible
548 to `Array<real_t> &`, see class MemoryView.
549
550 The simplest way to use this method is:
551 @code
552 func(*v.GetArrayView());
553 @endcode
554 where `func` has an `Array<real_t>&` argument and `v` is a Vector. In
555 this example, the returned MemoryView object is temporary, created just
556 before the call to `func` and destroyed automatically right after that
557 call.
558
559 Note that when the MemoryView is destroyed, the state of the underlying
560 Array<real_t> object is copied back to this Vector to reflect any changes
561 made to the Array.
562
563 Creating multiple views, of the same Vector object, that have overlapping
564 life spans is not supported. */
567
568 /** @brief Create a const view of the Vector as const Array<real_t> that can
569 be used to pass Vector objects to functions that take Array arguments.
570
571 The returned MemoryView object is implicitly and explicitly convertible
572 to `const Array<real_t> &`, see class MemoryView.
573
574 The simplest way to use this method is:
575 @code
576 func(*v.GetArrayView());
577 @endcode
578 where `func` has a `const Array<real_t>&` argument and `v` is a const
579 Vector. In this example, the returned MemoryView object is temporary,
580 created just before the call to `func` and destroyed automatically right
581 after that call.
582
583 Note that when the MemoryView is destroyed, the mutable part of the state
584 of the underlying const Array<real_t> object is copied back to this
585 Vector to reflect any changes made to the Array, e.g. if the data was
586 moved from host to device.
587
588 Creating multiple views, of the same Vector object, that have overlapping
589 life spans is not supported. */
592};
593
594// Inline methods
595
596template <typename T>
597inline T ZeroSubnormal(T val)
598{
599 return (std::fpclassify(val) == FP_SUBNORMAL) ? T{} : val;
600}
601
602inline bool IsFinite(const real_t &val)
603{
604 // isfinite didn't appear in a standard until C99, and later C++11. It wasn't
605 // standard in C89 or C++98. PGI as of 14.7 still defines it as a macro.
606#ifdef isfinite
607 return isfinite(val);
608#else
609 return std::isfinite(val);
610#endif
611}
612
613inline int CheckFinite(const real_t *v, const int n)
614{
615 int bad = 0;
616 for (int i = 0; i < n; i++)
617 {
618 if (!IsFinite(v[i])) { bad++; }
619 }
620 return bad;
621}
622
623inline Vector::Vector(int s)
624{
625 MFEM_ASSERT(s>=0,"Unexpected negative size.");
626 size = s;
627 if (s > 0)
628 {
629 data.New(s);
630 }
631}
632
633inline void Vector::SetSize(int s)
634{
635 if (s == size)
636 {
637 return;
638 }
639 if (s <= data.Capacity())
640 {
641 size = s;
642 return;
643 }
644 // preserve a valid MemoryType and device flag
645 const MemoryType mt = data.GetMemoryType();
646 const bool use_dev = data.UseDevice();
647 data.Delete();
648 size = s;
649 data.New(s, mt);
650 data.UseDevice(use_dev);
651}
652
653inline void Vector::SetSize(int s, MemoryType mt)
654{
655 if (mt == data.GetMemoryType())
656 {
657 if (s == size)
658 {
659 return;
660 }
661 if (s <= data.Capacity())
662 {
663 size = s;
664 return;
665 }
666 }
667 const bool use_dev = data.UseDevice();
668 data.Delete();
669 if (s > 0)
670 {
671 data.New(s, mt);
672 size = s;
673 }
674 else
675 {
676 data.Reset();
677 size = 0;
678 }
679 data.UseDevice(use_dev);
680}
681
682inline void Vector::Reserve(int res)
683{
684 if (res > Capacity())
685 {
687 p.CopyFrom(data, size);
688 p.UseDevice(data.UseDevice());
689 data.Delete();
690 data = p;
691 }
692}
693
694inline void Vector::NewMemoryAndSize(const Memory<real_t> &mem, int s,
695 bool own_mem)
696{
697 data.Delete();
698 size = s;
699 if (own_mem)
700 {
701 data = mem;
702 }
703 else
704 {
705 data.MakeAlias(mem, 0, s);
706 }
707}
708
709inline void Vector::MakeRef(Vector &base, int offset, int s)
710{
711 data.Delete();
712 size = s;
713 data.MakeAlias(base.GetMemory(), offset, s);
714}
715
716inline void Vector::MakeRef(Vector &base, int offset)
717{
718 data.Delete();
719 data.MakeAlias(base.GetMemory(), offset, size);
720}
721
722inline void Vector::Destroy()
723{
724 const bool use_dev = data.UseDevice();
725 data.Delete(); // calls data.Reset(h_mt) as well
726 size = 0;
727 data.UseDevice(use_dev);
728}
729
731{
732 MFEM_ASSERT(data && i >= 0 && i < size,
733 "index [" << i << "] is out of range [0," << size << ")");
734
735 return data[i];
736}
737
738inline const real_t &Vector::operator()(int i) const
739{
740 MFEM_ASSERT(data && i >= 0 && i < size,
741 "index [" << i << "] is out of range [0," << size << ")");
742
743 return data[i];
744}
745
746inline void Vector::Swap(Vector &other)
747{
748 mfem::Swap(data, other.data);
749 mfem::Swap(size, other.size);
750}
751
752/** @brief Swap of Vector objects for use with standard library algorithms.
753 Also, used by mfem::Swap(). */
754inline void swap(Vector &a, Vector &b)
755{
756 a.Swap(b);
757}
758
760{
761 data.Delete();
762}
763
764inline real_t DistanceSquared(const real_t *x, const real_t *y, const int n)
765{
766 real_t d = 0.0;
767
768 for (int i = 0; i < n; i++)
769 {
770 d += (x[i]-y[i])*(x[i]-y[i]);
771 }
772
773 return d;
774}
775
776inline real_t Distance(const real_t *x, const real_t *y, const int n)
777{
778 return std::sqrt(DistanceSquared(x, y, n));
779}
780
781inline real_t Distance(const Vector &x, const Vector &y)
782{
783 return x.DistanceTo(y);
784}
785
787{
788 return DistanceSquared(data, p, size);
789}
790
792{
793 MFEM_ASSERT(p.Size() == Size(), "Incompatible vector sizes.");
794 return DistanceSquared(data, p.data, size);
795}
796
797inline real_t Vector::DistanceTo(const real_t *p) const
798{
799 return Distance(data, p, size);
800}
801
802inline real_t Vector::DistanceTo(const Vector &p) const
803{
804 MFEM_ASSERT(p.Size() == Size(), "Incompatible vector sizes.");
805 return Distance(data, p.data, size);
806}
807
808/// Returns the inner product of x and y
809/** In parallel this computes the inner product of the local vectors,
810 producing different results on each MPI rank.
811*/
812inline real_t InnerProduct(const Vector &x, const Vector &y)
813{
814 return x * y;
815}
816
817#ifdef MFEM_USE_MPI
818/// Returns the inner product of x and y in parallel
819/** In parallel this computes the inner product of the global vectors,
820 producing identical results on each MPI rank.
821*/
822inline real_t InnerProduct(MPI_Comm comm, const Vector &x, const Vector &y)
823{
824 real_t loc_prod = x * y;
825 real_t glb_prod;
826 MPI_Allreduce(&loc_prod, &glb_prod, 1, MFEM_MPI_REAL_T, MPI_SUM, comm);
827 return glb_prod;
828}
829#endif
830
831} // namespace mfem
832
833#endif
Type that enables viewing Vector objects as Array<real_t> objects and vice versa. Currently,...
Class used by MFEM to store pointers to host and/or device memory.
void SetHostPtrOwner(bool own) const
Set/clear the ownership flag for the host pointer. Ownership indicates whether the pointer will be de...
int Capacity() const
Return the size of the allocated memory.
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
bool UseDevice() const
Read the internal device flag.
void SyncAlias(const Memory &base, int alias_size) const
Update the alias Memory *this to match the memory location (all valid locations) of its base Memory,...
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
void Sync(const Memory &other) const
Copy the host/device pointer validity flags from other to *this.
void DeleteDevice(bool copy_to_host=true)
Delete the device pointer, if owned. If copy_to_host is true and the data is valid only on device,...
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
void Wrap(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
void Delete()
Delete the owned pointers and reset the Memory object.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
Vector data type.
Definition vector.hpp:82
void Randomize(int seed=0)
Set random values in the vector.
Definition vector.cpp:955
void PrintHash(std::ostream &out) const
Print the Vector size and hash of its data.
Definition vector.cpp:947
void Pow(const real_t p)
(*this)(i) = pow((*this)(i), p)
Definition vector.cpp:403
real_t & Elem(int i)
Access Vector entries. Index i = 0 .. size-1.
Definition vector.cpp:173
Vector(int size_, MemoryType mt)
Create a Vector of size size_ using MemoryType mt.
Definition vector.hpp:116
void StealData(real_t **p)
Changes the ownership of the data; after the call the Vector is empty.
Definition vector.hpp:282
void SetSize(int s, const Vector &v)
Resize the vector to size s using the MemoryType of v.
Definition vector.hpp:173
void SetVector(const Vector &v, int offset)
(*this)[i + offset] = v[i]
Definition vector.cpp:353
MemoryView< const Array< real_t > > GetArrayView() const
Create a const view of the Vector as const Array<real_t> that can be used to pass Vector objects to f...
Definition vector.hpp:590
virtual const real_t * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
Definition vector.hpp:524
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:520
Vector(const CT(&values)[N])
Create a vector from a statically sized C-style array of convertible type.
Definition vector.hpp:126
const real_t & operator[](int i) const
Read only access to Vector entries using [] for 0-based indexing.
Definition vector.hpp:308
void median(const Vector &lo, const Vector &hi)
v = median(v,lo,hi) entrywise. Implementation assumes lo <= hi.
Definition vector.cpp:652
MemoryView< Array< real_t > > GetArrayView()
Create a mutable (non-const) view of the Vector as Array<real_t> that can be used to pass Vector obje...
Definition vector.hpp:565
void Load(std::istream &in)
Load a vector from an input stream, reading the size from the stream.
Definition vector.hpp:157
void Neg()
(*this) = -(*this)
Definition vector.cpp:376
real_t * begin()
STL-like begin.
Definition vector.hpp:253
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Definition vector.cpp:870
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:536
void SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
Definition vector.hpp:191
real_t operator*(const real_t *v) const
Definition vector.cpp:183
Vector(Vector &base, int base_offset, int size_)
Create a Vector referencing a sub-vector of the Vector base starting at the given offset,...
Definition vector.hpp:112
real_t Normlinf() const
Returns the l_infinity norm of the vector.
Definition vector.cpp:1004
void MakeDataOwner() const
Set the Vector data (host pointer) ownership flag.
Definition vector.hpp:222
real_t Norml1() const
Returns the l_1 norm of the vector.
Definition vector.cpp:1018
void SetSubVectorHost(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value (always on host).
Definition vector.cpp:723
bool OwnsData() const
Read the Vector data (host pointer) ownership flag.
Definition vector.hpp:279
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
Definition vector.cpp:702
friend void subtract(const Vector &v1, const Vector &v2, Vector &v)
Set v = v1 - v2.
Definition vector.cpp:570
Memory< real_t > & GetMemory()
Return a reference to the Memory object used by the Vector.
Definition vector.hpp:265
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add elements of the elemvect Vector to the entries listed in dofs. Negative dof values cause the -dof...
Definition vector.cpp:785
Memory< real_t > data
Definition vector.hpp:85
real_t & operator[](int i)
Access Vector entries using [] for 0-based indexing.
Definition vector.hpp:304
int CheckFinite() const
Count the number of entries in the Vector for which isfinite is false, i.e. the entry is a NaN or +/-...
Definition vector.hpp:514
void AddSubVector(const Vector &v, int offset)
(*this)[i + offset] += v[i]
Definition vector.cpp:365
const real_t * end() const
STL-like end (const version).
Definition vector.hpp:262
void Swap(Vector &other)
Swap the contents of two Vectors.
Definition vector.hpp:746
void DeleteAt(const Array< int > &indices)
Definition vector.cpp:1260
Vector & operator*=(real_t c)
Definition vector.cpp:241
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
Definition vector.hpp:275
real_t Norml2() const
Returns the l2 norm of the vector.
Definition vector.cpp:968
void SyncMemory(const Vector &v) const
Update the memory location of the vector to match v.
Definition vector.hpp:272
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
Definition vector.cpp:127
real_t DistanceSquaredTo(const real_t *p) const
Compute the square of the Euclidean distance to another vector.
Definition vector.hpp:786
Vector & Set(const real_t a, const Vector &x)
(*this) = a * x
Definition vector.cpp:341
real_t * end()
STL-like end.
Definition vector.hpp:256
const Memory< real_t > & GetMemory() const
Return a reference to the Memory object used by the Vector, const version.
Definition vector.hpp:269
void NewMemoryAndSize(const Memory< real_t > &mem, int s, bool own_mem)
Reset the Vector to use the given external Memory mem and size s.
Definition vector.hpp:694
real_t Max() const
Returns the maximal element of the vector.
Definition vector.cpp:1200
virtual bool UseDevice() const
Return the device flag of the Memory object used by the Vector.
Definition vector.hpp:148
Vector(int size_, MemoryType h_mt, MemoryType d_mt)
Create a Vector of size size_ using host MemoryType h_mt and device MemoryType d_mt.
Definition vector.hpp:121
void Destroy()
Destroy a vector.
Definition vector.hpp:722
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void Abs()
(*this)(i) = abs((*this)(i))
Definition vector.cpp:392
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
Definition vector.hpp:145
real_t Sum() const
Return the sum of the vector entries.
Definition vector.cpp:1246
void PrintMathematica(std::ostream &out=mfem::out) const
Prints vector as a List for importing into Mathematica.
Definition vector.cpp:923
void Print_HYPRE(std::ostream &out) const
Prints vector to stream out in HYPRE_Vector format.
Definition vector.cpp:904
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:633
void Reciprocal()
(*this)(i) = 1.0 / (*this)(i)
Definition vector.cpp:384
virtual real_t * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
Definition vector.hpp:532
void NewDataAndSize(real_t *d, int s)
Set the Vector data and size, deleting the old data, if owned.
Definition vector.hpp:197
real_t Normlp(real_t p) const
Returns the l_p norm of the vector.
Definition vector.cpp:1032
Vector & operator-=(real_t c)
Definition vector.cpp:284
const real_t * begin() const
STL-like begin (const version).
Definition vector.hpp:259
int Capacity() const
Return the size of the currently allocated data array.
Definition vector.hpp:238
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:243
Vector & operator=(const real_t *v)
Copy Size() entries from v.
Definition vector.cpp:197
void SetSubVectorComplement(const Array< int > &dofs, const real_t val)
Set all vector entries NOT in the dofs Array to the given val.
Definition vector.cpp:854
void SetData(real_t *d)
Definition vector.hpp:184
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
Definition vector.hpp:540
virtual ~Vector()
Destroys vector.
Definition vector.hpp:759
real_t Min() const
Returns the minimal element of the vector.
Definition vector.cpp:1154
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Definition vector.cpp:676
Vector & operator+=(real_t c)
Definition vector.cpp:305
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:528
real_t * StealData()
Changes the ownership of the data; after the call the Vector is empty.
Definition vector.hpp:286
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
Definition vector.cpp:326
real_t & operator()(int i)
Access Vector entries using () for 0-based indexing.
Definition vector.hpp:730
void DeleteDevice(bool copy_to_host=true)
Delete the device pointer, if owned. If copy_to_host is true and the data is valid only on device,...
Definition vector.hpp:230
Vector(real_t *data_, int size_)
Creates a vector referencing an array of doubles, owned by someone else.
Definition vector.hpp:107
void cross3D(const Vector &vin, Vector &vout) const
Definition vector.cpp:639
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
Definition vector.hpp:709
Vector(std::initializer_list< CT > values)
Create a vector using a braced initializer list.
Definition vector.hpp:132
Vector & operator/=(real_t c)
Definition vector.cpp:262
void Reserve(int res)
Update Capacity() to res (if less than current), keeping existing entries.
Definition vector.hpp:682
friend void add(const Vector &v1, const Vector &v2, Vector &v)
Set v = v1 + v2.
Definition vector.cpp:414
real_t DistanceTo(const real_t *p) const
Compute the Euclidean distance to another vector.
Definition vector.hpp:797
const real_t alpha
Definition ex15.cpp:369
int dim
Definition ex24.cpp:53
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
mfem::real_t real_t
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
Definition device.hpp:369
void swap(Array< T > &a, Array< T > &b)
Swap of Array<T> objects for use with standard library algorithms. Also, used by mfem::Swap().
Definition array.hpp:776
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
Definition device.hpp:386
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
real_t rand_real()
Generate a random real_t number in the interval [0,1) using rand().
Definition vector.hpp:61
bool IsFinite(const real_t &val)
Definition vector.hpp:602
real_t Distance(const real_t *x, const real_t *y, const int n)
Definition vector.hpp:776
real_t InnerProduct(HypreParVector *x, HypreParVector *y)
Definition hypre.cpp:471
real_t DistanceSquared(const real_t *x, const real_t *y, const int n)
Definition vector.hpp:764
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device's DeviceMemoryClass,...
Definition device.hpp:403
void Swap(T &a, T &b)
Swap objects of type T. The operation is performed using the most specialized swap function from the ...
Definition array.hpp:767
int CheckFinite(const real_t *v, const int n)
Definition vector.hpp:613
T ZeroSubnormal(T val)
Definition vector.hpp:597
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.
constexpr real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
Definition vector.hpp:47
real_t p(const Vector &x, real_t t)