MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
vector.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, 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__
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};
544
545// Inline methods
546
547template <typename T>
548inline T ZeroSubnormal(T val)
549{
550 return (std::fpclassify(val) == FP_SUBNORMAL) ? 0.0 : val;
551}
552
553inline bool IsFinite(const real_t &val)
554{
555 // isfinite didn't appear in a standard until C99, and later C++11. It wasn't
556 // standard in C89 or C++98. PGI as of 14.7 still defines it as a macro.
557#ifdef isfinite
558 return isfinite(val);
559#else
560 return std::isfinite(val);
561#endif
562}
563
564inline int CheckFinite(const real_t *v, const int n)
565{
566 int bad = 0;
567 for (int i = 0; i < n; i++)
568 {
569 if (!IsFinite(v[i])) { bad++; }
570 }
571 return bad;
572}
573
574inline Vector::Vector(int s)
575{
576 MFEM_ASSERT(s>=0,"Unexpected negative size.");
577 size = s;
578 if (s > 0)
579 {
580 data.New(s);
581 }
582}
583
584inline void Vector::SetSize(int s)
585{
586 if (s == size)
587 {
588 return;
589 }
590 if (s <= data.Capacity())
591 {
592 size = s;
593 return;
594 }
595 // preserve a valid MemoryType and device flag
596 const MemoryType mt = data.GetMemoryType();
597 const bool use_dev = data.UseDevice();
598 data.Delete();
599 size = s;
600 data.New(s, mt);
601 data.UseDevice(use_dev);
602}
603
604inline void Vector::SetSize(int s, MemoryType mt)
605{
606 if (mt == data.GetMemoryType())
607 {
608 if (s == size)
609 {
610 return;
611 }
612 if (s <= data.Capacity())
613 {
614 size = s;
615 return;
616 }
617 }
618 const bool use_dev = data.UseDevice();
619 data.Delete();
620 if (s > 0)
621 {
622 data.New(s, mt);
623 size = s;
624 }
625 else
626 {
627 data.Reset();
628 size = 0;
629 }
630 data.UseDevice(use_dev);
631}
632
633inline void Vector::Reserve(int res)
634{
635 if (res > Capacity())
636 {
638 p.CopyFrom(data, size);
639 p.UseDevice(data.UseDevice());
640 data.Delete();
641 data = p;
642 }
643}
644
645inline void Vector::NewMemoryAndSize(const Memory<real_t> &mem, int s,
646 bool own_mem)
647{
648 data.Delete();
649 size = s;
650 if (own_mem)
651 {
652 data = mem;
653 }
654 else
655 {
656 data.MakeAlias(mem, 0, s);
657 }
658}
659
660inline void Vector::MakeRef(Vector &base, int offset, int s)
661{
662 data.Delete();
663 size = s;
664 data.MakeAlias(base.GetMemory(), offset, s);
665}
666
667inline void Vector::MakeRef(Vector &base, int offset)
668{
669 data.Delete();
670 data.MakeAlias(base.GetMemory(), offset, size);
671}
672
673inline void Vector::Destroy()
674{
675 const bool use_dev = data.UseDevice();
676 data.Delete(); // calls data.Reset(h_mt) as well
677 size = 0;
678 data.UseDevice(use_dev);
679}
680
682{
683 MFEM_ASSERT(data && i >= 0 && i < size,
684 "index [" << i << "] is out of range [0," << size << ")");
685
686 return data[i];
687}
688
689inline const real_t &Vector::operator()(int i) const
690{
691 MFEM_ASSERT(data && i >= 0 && i < size,
692 "index [" << i << "] is out of range [0," << size << ")");
693
694 return data[i];
695}
696
697inline void Vector::Swap(Vector &other)
698{
699 mfem::Swap(data, other.data);
700 mfem::Swap(size, other.size);
701}
702
703/** @brief Swap of Vector objects for use with standard library algorithms.
704 Also, used by mfem::Swap(). */
705inline void swap(Vector &a, Vector &b)
706{
707 a.Swap(b);
708}
709
711{
712 data.Delete();
713}
714
715inline real_t DistanceSquared(const real_t *x, const real_t *y, const int n)
716{
717 real_t d = 0.0;
718
719 for (int i = 0; i < n; i++)
720 {
721 d += (x[i]-y[i])*(x[i]-y[i]);
722 }
723
724 return d;
725}
726
727inline real_t Distance(const real_t *x, const real_t *y, const int n)
728{
729 return std::sqrt(DistanceSquared(x, y, n));
730}
731
732inline real_t Distance(const Vector &x, const Vector &y)
733{
734 return x.DistanceTo(y);
735}
736
738{
739 return DistanceSquared(data, p, size);
740}
741
743{
744 MFEM_ASSERT(p.Size() == Size(), "Incompatible vector sizes.");
745 return DistanceSquared(data, p.data, size);
746}
747
748inline real_t Vector::DistanceTo(const real_t *p) const
749{
750 return Distance(data, p, size);
751}
752
753inline real_t Vector::DistanceTo(const Vector &p) const
754{
755 MFEM_ASSERT(p.Size() == Size(), "Incompatible vector sizes.");
756 return Distance(data, p.data, size);
757}
758
759/// Returns the inner product of x and y
760/** In parallel this computes the inner product of the local vectors,
761 producing different results on each MPI rank.
762*/
763inline real_t InnerProduct(const Vector &x, const Vector &y)
764{
765 return x * y;
766}
767
768#ifdef MFEM_USE_MPI
769/// Returns the inner product of x and y in parallel
770/** In parallel this computes the inner product of the global vectors,
771 producing identical results on each MPI rank.
772*/
773inline real_t InnerProduct(MPI_Comm comm, const Vector &x, const Vector &y)
774{
775 real_t loc_prod = x * y;
776 real_t glb_prod;
777 MPI_Allreduce(&loc_prod, &glb_prod, 1, MFEM_MPI_REAL_T, MPI_SUM, comm);
778 return glb_prod;
779}
780#endif
781
782} // namespace mfem
783
784#endif
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
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
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:697
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:737
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:645
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:673
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:584
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:710
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:681
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:660
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:633
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:748
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:348
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:747
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
Definition vector.hpp:47
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:365
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:553
real_t Distance(const real_t *x, const real_t *y, const int n)
Definition vector.hpp:727
real_t InnerProduct(HypreParVector *x, HypreParVector *y)
Definition hypre.cpp:468
real_t DistanceSquared(const real_t *x, const real_t *y, const int n)
Definition vector.hpp:715
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:382
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:738
int CheckFinite(const real_t *v, const int n)
Definition vector.hpp:564
T ZeroSubnormal(T val)
Definition vector.hpp:548
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.
real_t p(const Vector &x, real_t t)