MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
array.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_ARRAY
13#define MFEM_ARRAY
14
15#include "../config/config.hpp"
16#include "mem_manager.hpp"
17#include "device.hpp"
18#include "error.hpp"
19#include "globals.hpp"
20
21#include <iostream>
22#include <cstdlib>
23#include <cstring>
24#include <algorithm>
25#include <type_traits>
26#include <initializer_list>
27
28namespace mfem
29{
30
31/** @brief Swap objects of type T. The operation is performed using the most
32 specialized `swap` function from the `mfem` namespace (or other visible
33 `swap` functions), or using the `std::swap` generic template and its
34 specializations in the standard library. */
35template <class T> inline void Swap(T &a, T &b);
36
37
38/**
39 Abstract data type Array.
40
41 Array<T> is an automatically increasing array containing elements of the
42 generic type T, which must be a trivial type, see `std::is_trivial`. The
43 allocated size may be larger then the logical size of the array. The elements
44 can be accessed by the [] operator, the range is 0 to size-1.
45*/
46template <class T>
47class Array
48{
49protected:
50 /// Pointer to data
52 /// Size of the array
53 int size;
54
55 inline void GrowSize(int minsize);
56
57 static_assert(std::is_trivial<T>::value, "type T must be trivial");
58
59public:
60 using value_type = T; ///< Type alias for stl.
61 using reference = T&; ///< Type alias for stl.
62 using const_reference = const T&; ///< Type alias for stl.
63
64 /// Creates an empty array
65 inline Array() : size(0) { }
66
67 /// Creates an empty array with a given MemoryType
68 inline Array(MemoryType mt) : data(mt), size(0) { }
69
70 /// Creates array of @a asize elements
71 explicit inline Array(int asize)
72 : size(asize) { if (asize > 0) { data.New(asize); } }
73
74 /// Creates array of @a asize elements with a given MemoryType
75 inline Array(int asize, MemoryType mt)
76 : data(mt), size(asize) { if (asize > 0) { data.New(asize, mt); } }
77
78 /** @brief Creates array using an externally allocated host pointer @a data_
79 to @a asize elements. If @a own_data is true, the array takes ownership
80 of the pointer.
81
82 When @a own_data is true, the pointer @a data_ must be allocated with
83 MemoryType given by MemoryManager::GetHostMemoryType(). */
84 inline Array(T *data_, int asize, bool own_data = false)
85 { data.Wrap(data_, asize, own_data); size = asize; }
86
87 /// Copy constructor: deep copy from @a src
88 /** This method supports source arrays using any MemoryType. */
89 inline Array(const Array &src);
90
91 /// Copy constructor (deep copy) from 'src', an Array of convertible type.
92 template <typename CT>
93 inline Array(const Array<CT> &src);
94
95 /// Construct an Array from a C-style array of static length
96 template <typename CT, int N>
97 explicit inline Array(const CT (&values)[N]);
98
99 /// Construct an Array from a braced initializer list of convertible type
100 template <typename CT, typename std::enable_if<
101 std::is_convertible<CT,T>::value,bool>::type = true>
102 explicit inline Array(std::initializer_list<CT> values);
103
104 /// Move constructor ("steals" data from 'src')
105 Array(Array<T> &&src) : data(std::move(src.data)), size(src.size)
106 {
107 src.size = 0;
108 }
109
110 /// Destructor
111 inline ~Array() { data.Delete(); }
112
113 /// Copy assignment operator: deep copy from 'src'.
114 Array<T> &operator=(const Array<T> &src) { src.Copy(*this); return *this; }
115
116 /// Move assignment operator
118 {
119 if (this == &src) { return *this; }
120 Swap(src); // Swap does not use move assignment!
121 src.DeleteAll();
122 return *this;
123 }
124
125 /// Assignment operator (deep copy) from @a src, an Array of convertible type.
126 template <typename CT>
127 inline Array &operator=(const Array<CT> &src);
128
129 /// Swap the contents of the Array with @a other.
130 /** Implemented without using move assignment, avoiding DeleteAll() calls. */
131 inline void Swap(Array &other);
132
133 /// Return the data as 'T *'
134 inline operator T *() { return data; }
135
136 /// Return the data as 'const T *'
137 inline operator const T *() const { return data; }
138
139 /// Returns the data
140 inline T *GetData() { return data; }
141 /// Returns the data
142 inline const T *GetData() const { return data; }
143
144 /// Return a reference to the Memory object used by the Array.
145 Memory<T> &GetMemory() { return data; }
146
147 /// Return a reference to the Memory object used by the Array, const version.
148 const Memory<T> &GetMemory() const { return data; }
149
150 /// Return the device flag of the Memory object used by the Array
151 bool UseDevice() const { return data.UseDevice(); }
152
153 /// Return true if the data will be deleted by the Array
154 inline bool OwnsData() const { return data.OwnsHostPtr(); }
155
156 /// Changes the ownership of the data
157 inline void StealData(T **p) { *p = data; data.Reset(); size = 0; }
158
159 /// NULL-ifies the data
160 inline void LoseData() { data.Reset(); size = 0; }
161
162 /// Make the Array own the data
163 void MakeDataOwner() const { data.SetHostPtrOwner(true); }
164
165 /// Return the logical size of the array.
166 inline int Size() const { return size; }
167
168 /// Change the logical size of the array, keep existing entries.
169 inline void SetSize(int nsize);
170
171 /// Same as SetSize(int) plus initialize new entries with 'initval'.
172 inline void SetSize(int nsize, const T &initval);
173
174 /** @brief Resize the array to size @a nsize using MemoryType @a mt. Note
175 that unlike the other versions of SetSize(), the current content of the
176 array is not preserved. */
177 inline void SetSize(int nsize, MemoryType mt);
178
179 /** Maximum number of entries the array can store without allocating more
180 memory. */
181 inline int Capacity() const { return data.Capacity(); }
182
183 /// Ensures that the allocated size is at least the given size.
184 inline void Reserve(int capacity)
185 { if (capacity > Capacity()) { GrowSize(capacity); } }
186
187 /// Reference access to the ith element.
188 inline T & operator[](int i);
189
190 /// Const reference access to the ith element.
191 inline const T &operator[](int i) const;
192
193 /// Append element 'el' to array, resize if necessary.
194 inline int Append(const T & el);
195
196 /// STL-like push_back. Append element 'el' to array, resize if necessary.
197 void push_back(const T &el) { Append(el); }
198
199 /// Append another array to this array, resize if necessary.
200 inline int Append(const T *els, int nels);
201
202 /// Append another array to this array, resize if necessary.
203 inline int Append(const Array<T> &els) { return Append(els, els.Size()); }
204
205 /// Prepend an 'el' to the array, resize if necessary.
206 inline int Prepend(const T &el);
207
208 /// Return the last element in the array.
209 inline T &Last();
210
211 /// Return the last element in the array.
212 inline const T &Last() const;
213
214 /// Append element when it is not yet in the array, return index.
215 inline int Union(const T & el);
216
217 /// Return the first index where 'el' is found; return -1 if not found.
218 inline int Find(const T &el) const;
219
220 /// Do bisection search for 'el' in a sorted array; return -1 if not found.
221 inline int FindSorted(const T &el) const;
222
223 /// Delete the last entry of the array.
224 inline void DeleteLast() { if (size > 0) { size--; } }
225
226 /// Delete the first entry with value == 'el'.
227 inline void DeleteFirst(const T &el);
228
229 /// Delete entries at @a indices, and resize.
230 inline void DeleteAt(const Array<int> &indices);
231
232 /// Delete the whole array.
233 inline void DeleteAll();
234
235 /// Reduces the capacity of the array to exactly match the current size.
236 inline void ShrinkToFit();
237
238 /// Create a copy of the internal array to the provided @a copy.
239 inline void Copy(Array &copy) const;
240
241 /// Make this Array a reference to a pointer.
242 /** When @a own_data is true, the pointer @a data_ must be allocated with
243 MemoryType given by MemoryManager::GetHostMemoryType(). */
244 inline void MakeRef(T *data_, int size_, bool own_data = false);
245
246 /// Make this Array a reference to a pointer.
247 /** When @a own_data is true, the pointer @a data_ must be allocated with
248 MemoryType given by @a mt. */
249 inline void MakeRef(T *data_, int size, MemoryType mt, bool own_data);
250
251 /// Make this Array a reference to 'master'.
252 inline void MakeRef(const Array &master);
253
254 /// Reset the Array to use the given external Memory @a mem and size @a s.
255 /** If @a own_mem is false, the Array will not own any of the pointers of
256 @a mem.
257
258 Note that when @a own_mem is true, the @a mem object can be destroyed
259 immediately by the caller but `mem.Delete()` should NOT be called since
260 the Array object takes ownership of all pointers owned by @a mem. */
261 inline void NewMemoryAndSize(const Memory<T> &mem, int s, bool own_mem);
262
263 /**
264 * @brief Permute the array using the provided indices. Sorts the indices
265 * variable in the process, thereby destroying the permutation. The rvalue
266 * reference is to be used when this destruction is allowed, whilst the const
267 * reference preserves at the cost of duplication.
268 *
269 * @param indices The indices of the ordering. data[i] = data[indices[i]].
270 */
271 template <typename I>
272 inline void Permute(I &&indices);
273 template <typename I>
274 inline void Permute(const I &indices) { Permute(I(indices)); }
275
276 /// Copy sub array starting from @a offset out to the provided @a sa.
277 inline void GetSubArray(int offset, int sa_size, Array<T> &sa) const;
278
279 /// Prints array to stream with width elements per row.
280 void Print(std::ostream &out = mfem::out, int width = 4) const;
281
282 /** @brief Save the Array to the stream @a out using the format @a fmt.
283 The format @a fmt can be:
284
285 0 - write the size followed by all entries
286 1 - write only the entries
287 */
288 void Save(std::ostream &out, int fmt = 0) const;
289
290 /** @brief Read an Array from the stream @a in using format @a fmt.
291 The format @a fmt can be:
292
293 0 - read the size then the entries
294 1 - read Size() entries
295 */
296 void Load(std::istream &in, int fmt = 0);
297
298 /** @brief Set the Array size to @a new_size and read that many entries from
299 the stream @a in. */
300 void Load(int new_size, std::istream &in)
301 { SetSize(new_size); Load(in, 1); }
302
303 /** @brief Find the maximal element in the array, using the comparison
304 operator `<` for class T. */
305 T Max() const;
306
307 /** @brief Find the minimal element in the array, using the comparison
308 operator `<` for class T. */
309 T Min() const;
310
311 /// Sorts the array in ascending order. This requires operator< to be defined for T.
312 void Sort() { std::sort((T*)data, data + size); }
313
314 /// Sorts the array in ascending order using the supplied comparison function object.
315 template<class Compare>
316 void Sort(Compare cmp) { std::sort((T*)data, data + size, cmp); }
317
318 /** @brief Removes duplicities from a sorted array. This requires
319 operator== to be defined for T. */
320 void Unique()
321 {
322 T* end = std::unique((T*)data, data + size);
323 SetSize((int)(end - data));
324 }
325
326 /// Return 1 if the array is sorted from lowest to highest. Otherwise return 0.
327 int IsSorted() const;
328
329 /// Does the Array have Size zero.
330 bool IsEmpty() const { return Size() == 0; }
331
332 /// Return true if all entries of the array are the same.
333 bool IsConstant() const;
334
335 /// Fill the entries of the array with the cumulative sum of the entries.
336 void PartialSum();
337
338 /// Replace each entry of the array with its absolute value.
339 void Abs();
340
341 /// Return the sum of all the array entries using the '+'' operator for class 'T'.
342 T Sum() const;
343
344 /// Set all entries of the array to the provided constant.
345 inline void operator=(const T &a);
346
347 /// Copy data from a pointer. 'Size()' elements are copied.
348 inline void Assign(const T *);
349
350 /// STL-like copyTo @a dest from begin to end.
351 template <typename U>
352 inline void CopyTo(U *dest) { std::copy(begin(), end(), dest); }
353
354 /** @brief Copy from @a src into this array. Copies enough entries to
355 fill the Capacity size of this array. Careful this does not update
356 the Size to match this Capacity after this.*/
357 template <typename U>
358 inline void CopyFrom(const U *src)
359 {
360 if (!begin() || size == 0) { return; }
361 MFEM_ASSERT(begin() && src, "Error in Array::CopyFrom");
362 std::memcpy(begin(), src, MemoryUsage());
363 }
364
365 /// STL-like begin. Returns pointer to the first element of the array.
366 inline T* begin() { return data; }
367
368 /// STL-like end. Returns pointer after the last element of the array.
369 inline T* end() { return data + size; }
370
371 /// STL-like begin. Returns const pointer to the first element of the array.
372 inline const T* begin() const { return data; }
373
374 /// STL-like end. Returns const pointer after the last element of the array.
375 inline const T* end() const { return data + size; }
376
377 /// Returns the number of bytes allocated for the array including any reserve.
378 std::size_t MemoryUsage() const { return Capacity() * sizeof(T); }
379
380 /// Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
381 const T *Read(bool on_dev = true) const
382 { return mfem::Read(data, size, on_dev); }
383
384 /// Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
385 const T *HostRead() const
386 { return mfem::Read(data, size, false); }
387
388 /// Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
389 T *Write(bool on_dev = true)
390 { return mfem::Write(data, size, on_dev); }
391
392 /// Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
394 { return mfem::Write(data, size, false); }
395
396 /// Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
397 T *ReadWrite(bool on_dev = true)
398 { return mfem::ReadWrite(data, size, on_dev); }
399
400 /// Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
402 { return mfem::ReadWrite(data, size, false); }
403};
404
405template <class T>
406inline bool operator==(const Array<T> &LHS, const Array<T> &RHS)
407{
408 if ( LHS.Size() != RHS.Size() ) { return false; }
409 for (int i=0; i<LHS.Size(); i++)
410 {
411 if ( LHS[i] != RHS[i] ) { return false; }
412 }
413 return true;
414}
415
416template <class T>
417inline bool operator!=(const Array<T> &LHS, const Array<T> &RHS)
418{
419 return !( LHS == RHS );
420}
421
422
423/// Utility function similar to std::as_const in c++17.
424template <typename T> const T &AsConst(const T &a) { return a; }
425
426
427/// Dynamic 2D array using row-major layout
428template <class T>
430{
431private:
432 Array<T> array1d;
433 int M, N; // number of rows and columns
434
435public:
436 Array2D() { M = N = 0; }
437
438 /// Construct an m x n 2D array.
439 Array2D(int m, int n) : array1d(m*n) { M = m; N = n; }
440
441 Array2D(const Array2D &) = default;
442 Array2D(Array2D &&) = default;
443
444 /// Set the 2D array size to m x n.
445 void SetSize(int m, int n) { array1d.SetSize(m*n); M = m; N = n; }
446
447 int NumRows() const { return M; }
448 int NumCols() const { return N; }
449
450 inline const T &operator()(int i, int j) const;
451 inline T &operator()(int i, int j);
452
453 inline const T *operator[](int i) const;
454 inline T *operator[](int i);
455
456 const T *operator()(int i) const { return (*this)[i]; }
457 T *operator()(int i) { return (*this)[i]; }
458
459 const T *GetRow(int i) const { return (*this)[i]; }
460 T *GetRow(int i) { return (*this)[i]; }
461
462 /// Extract a copy of the @a i-th row into the Array @a sa.
463 void GetRow(int i, Array<T> &sa) const
464 {
465 sa.SetSize(N);
466 sa.Assign(GetRow(i));
467 }
468
469 /** @brief Save the Array2D to the stream @a out using the format @a fmt.
470
471 The format @a fmt can be:
472 - 0 - write the number of rows and columns, followed by all entries
473 - 1 - write only the entries, using row-major layout
474 */
475 void Save(std::ostream &os, int fmt = 0) const
476 {
477 if (fmt == 0) { os << NumRows() << ' ' << NumCols() << '\n'; }
478 array1d.Save(os, 1);
479 }
480
481 /** @brief Read an Array2D from the stream @a in using format @a fmt.
482
483 The format @a fmt can be:
484 - 0 - read the number of rows and columns, then the entries
485 - 1 - read NumRows() x NumCols() entries, using row-major layout
486 */
487 void Load(std::istream &in, int fmt = 0)
488 {
489 if (fmt == 0) { in >> M >> N; array1d.SetSize(M*N); }
490 array1d.Load(in, 1);
491 }
492
493 /// Read an Array2D from a file
494 void Load(const char *filename, int fmt = 0);
495
496 /** @brief Set the Array2D dimensions to @a new_size0 x @a new_size1 and read
497 that many entries from the stream @a in. */
498 void Load(int new_size0,int new_size1, std::istream &in)
499 { SetSize(new_size0,new_size1); Load(in, 1); }
500
501 void Copy(Array2D &copy) const { copy = *this; }
502
503 /// Set all entries of the array to the provided constant.
504 inline void operator=(const T &a)
505 { array1d = a; }
506
507 /// Copy assignment.
508 Array2D& operator=(const Array2D &) = default;
509
510 /// Move assignment.
511 Array2D& operator=(Array2D &&) = default;
512
513 /// Swap the contents of the Array2D with @a other.
514 /** Implemented without using move assignment, avoiding some unnecessary
515 calls. */
516 inline void Swap(Array2D &other);
517
518 /// Make this Array2D a reference to 'master'
519 inline void MakeRef(const Array2D &master)
520 { M = master.M; N = master.N; array1d.MakeRef(master.array1d); }
521
522 /// Delete all dynamically allocated memory, resetting all dimensions to zero.
523 inline void DeleteAll() { M = 0; N = 0; array1d.DeleteAll(); }
524
525 /// Prints array to stream with width elements per row
526 void Print(std::ostream &out = mfem::out, int width = 4);
527
528 /** @brief Find the maximal element in the array, using the comparison
529 operator `<` for class T. */
530 T Max() const { return array1d.Max(); }
531
532 /** @brief Find the minimal element in the array, using the comparison
533 operator `<` for class T. */
534 T Min() const { return array1d.Min(); }
535};
536
537
538template <class T>
540{
541private:
542 Array<T> array1d;
543 int N2, N3;
544
545public:
546 Array3D() { N2 = N3 = 0; }
547
548 /// Construct a 3D array of size n1 x n2 x n3.
549 Array3D(int n1, int n2, int n3)
550 : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
551
552 /// Set the 3D array size to n1 x n2 x n3.
553 void SetSize(int n1, int n2, int n3)
554 { array1d.SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
555
556 /// Get the 3D array size in the first dimension.
557 int GetSize1() const
558 {
559 const int size = array1d.Size();
560 return size == 0 ? 0 : size / (N2 * N3);
561 }
562
563 /// Get the 3D array size in the second dimension.
564 int GetSize2() const { return N2; }
565
566 /// Get the 3D array size in the third dimension.
567 int GetSize3() const { return N3; }
568
569 inline const T &operator()(int i, int j, int k) const;
570 inline T &operator()(int i, int j, int k);
571
572 /// Set all entries of the array to the provided constant.
573 inline void operator=(const T &a)
574 { array1d = a; }
575};
576
577
578/** A container for items of type T. Dynamically grows as items are added.
579 * Each item is accessible by its index. Items are allocated in larger chunks
580 * (blocks), so the 'Append' method is very fast on average.
581 */
582template<typename T>
584{
585public:
586 BlockArray(int block_size = 16*1024);
587 BlockArray(const BlockArray<T> &other); // deep copy
588 BlockArray& operator=(const BlockArray&) = delete; // not supported
589 BlockArray(BlockArray<T> &&other) = default;
590 BlockArray& operator=(BlockArray<T> &&other) = default;
592
593 /// Allocate and construct a new item in the array, return its index.
594 int Append();
595
596 /// Allocate and copy-construct a new item in the array, return its index.
597 int Append(const T &item);
598
599 /// Access item of the array.
600 inline T& At(int index)
601 {
603 return blocks[index >> shift][index & mask];
604 }
605 inline const T& At(int index) const
606 {
608 return blocks[index >> shift][index & mask];
609 }
610
611 /// Access item of the array.
612 inline T& operator[](int index) { return At(index); }
613 inline const T& operator[](int index) const { return At(index); }
614
615 /// Return the number of items actually stored.
616 int Size() const { return size; }
617
618 /// Return the current capacity of the BlockArray.
619 int Capacity() const { return blocks.Size()*(mask+1); }
620
621 /// Destroy all items, set size to zero.
622 void DeleteAll() { Destroy(); blocks.DeleteAll(); size = 0; }
623
624 void Swap(BlockArray<T> &other);
625
626 std::size_t MemoryUsage() const;
627
628protected:
629 template <typename cA, typename cT>
631 {
632 public:
633 cT& operator*() const { return *ptr; }
634 cT* operator->() const { return ptr; }
635
636 bool good() const { return !stop; }
637 int index() const { return (ptr - ref); }
638
639 protected:
640 cA *array;
641 cT *ptr, *b_end, *ref;
643 bool stop;
644
648 : array(a), ptr(a->blocks[0]), ref(ptr), stop(false)
649 {
650 b_end_idx = std::min(a->size, a->mask+1);
651 b_end = ptr + b_end_idx;
652 }
653
654 void next()
655 {
656 MFEM_ASSERT(!stop, "invalid use");
657 if (++ptr == b_end)
658 {
660 {
661 ptr = &array->At(b_end_idx);
662 ref = ptr - b_end_idx;
663 b_end_idx = std::min(array->size, (b_end_idx|array->mask) + 1);
664 b_end = &array->At(b_end_idx-1) + 1;
665 }
666 else
667 {
668 MFEM_ASSERT(b_end_idx == array->size, "invalid use");
669 stop = true;
670 }
671 }
672 }
673 };
674
675public:
676 class iterator : public iterator_base<BlockArray, T>
677 {
678 protected:
679 friend class BlockArray;
681
683 iterator(bool stop) : base(stop) { }
685
686 public:
687 iterator &operator++() { base::next(); return *this; }
688
689 bool operator==(const iterator &other) const { return base::stop; }
690 bool operator!=(const iterator &other) const { return !base::stop; }
691 };
692
693 class const_iterator : public iterator_base<const BlockArray, const T>
694 {
695 protected:
696 friend class BlockArray;
698
702
703 public:
704 const_iterator &operator++() { base::next(); return *this; }
705
706 bool operator==(const const_iterator &other) const { return base::stop; }
707 bool operator!=(const const_iterator &other) const { return !base::stop; }
708 };
709
710 iterator begin() { return size ? iterator(this) : iterator(true); }
711 iterator end() { return iterator(); }
712 const_iterator begin() const { return cbegin(); }
713 const_iterator end() const { return cend(); }
714
716 { return size ? const_iterator(this) : const_iterator(true); }
717 const_iterator cend() const { return const_iterator(); }
718
719protected:
722
723 int Alloc();
724
725 inline void CheckIndex(int index) const
726 {
727 MFEM_ASSERT(index >= 0 && index < size,
728 "Out of bounds access: " << index << ", size = " << size);
729 }
730
731 void Destroy();
732};
733
734
735// Inlines
736
737
738template <class T> inline void Swap(T &a, T &b)
739{
740 using std::swap;
741 swap(a, b);
742}
743
744/** @brief Swap of Array<T> objects for use with standard library algorithms.
745 Also, used by mfem::Swap(). */
746template <typename T>
747inline void swap(Array<T> &a, Array<T> &b)
748{
749 // swap without using move assignment
750 a.Swap(b);
751}
752
753template <class T>
754inline Array<T>::Array(const Array &src)
755 : size(src.Size())
756{
757 size > 0 ? data.New(size, src.data.GetMemoryType()) : data.Reset();
758 data.CopyFrom(src.data, size);
759 data.UseDevice(src.data.UseDevice());
760}
761
762template <typename T> template <typename CT>
763inline Array<T>::Array(const Array<CT> &src)
764 : size(src.Size())
765{
766 size > 0 ? data.New(size) : data.Reset();
767 for (int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
768}
769
770template <typename T>
771template <typename CT, typename std::enable_if<
772 std::is_convertible<CT,T>::value,bool>::type>
773inline Array<T>::Array(std::initializer_list<CT> values) : Array(values.size())
774{
775 std::copy(values.begin(), values.end(), begin());
776}
777
778template <typename T> template <typename CT, int N>
779inline Array<T>::Array(const CT (&values)[N]) : Array(N)
780{
781 std::copy(values, values + N, begin());
782}
783
784template <class T>
785inline void Array<T>::Swap(Array &other)
786{
787 mfem::Swap(data, other.data);
788 std::swap(size, other.size);
789}
790
791template <class T>
792inline void Array<T>::GrowSize(int minsize)
793{
794 const int nsize = std::max(minsize, 2 * data.Capacity());
795 Memory<T> p(nsize, data.GetMemoryType());
796 p.CopyFrom(data, size);
797 p.UseDevice(data.UseDevice());
798 data.Delete();
799 data = p;
800}
801
802template <typename T>
804{
805 if (Capacity() == size) { return; }
806 Memory<T> p(size, data.GetMemoryType());
807 p.CopyFrom(data, size);
808 p.UseDevice(data.UseDevice());
809 data.Delete();
810 data = p;
811}
812
813template <typename T>
814template <typename I>
815inline void Array<T>::Permute(I &&indices)
816{
817 for (int i = 0; i < size; i++)
818 {
819 auto current = i;
820 while (i != indices[current])
821 {
822 auto next = indices[current];
823 std::swap(data[current], data[next]);
824 indices[current] = current;
825 current = next;
826 }
827 indices[current] = current;
828 }
829}
830
831template <typename T> template <typename CT>
833{
834 SetSize(src.Size());
835 for (int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
836 return *this;
837}
838
839template <class T>
840inline void Array<T>::SetSize(int nsize)
841{
842 MFEM_ASSERT( nsize>=0, "Size must be non-negative. It is " << nsize );
843 if (nsize > Capacity())
844 {
845 GrowSize(nsize);
846 }
847 size = nsize;
848}
849
850template <class T>
851inline void Array<T>::SetSize(int nsize, const T &initval)
852{
853 MFEM_ASSERT( nsize>=0, "Size must be non-negative. It is " << nsize );
854 if (nsize > size)
855 {
856 if (nsize > Capacity())
857 {
858 GrowSize(nsize);
859 }
860 for (int i = size; i < nsize; i++)
861 {
862 data[i] = initval;
863 }
864 }
865 size = nsize;
866}
867
868template <class T>
869inline void Array<T>::SetSize(int nsize, MemoryType mt)
870{
871 MFEM_ASSERT(nsize >= 0, "invalid new size: " << nsize);
872 if (mt == data.GetMemoryType())
873 {
874 if (nsize <= Capacity())
875 {
876 size = nsize;
877 return;
878 }
879 }
880 const bool use_dev = data.UseDevice();
881 data.Delete();
882 if (nsize > 0)
883 {
884 data.New(nsize, mt);
885 size = nsize;
886 }
887 else
888 {
889 data.Reset();
890 size = 0;
891 }
892 data.UseDevice(use_dev);
893}
894
895template <class T>
896inline T &Array<T>::operator[](int i)
897{
898 MFEM_ASSERT( i>=0 && i<size,
899 "Access element " << i << " of array, size = " << size );
900 return data[i];
901}
902
903template <class T>
904inline const T &Array<T>::operator[](int i) const
905{
906 MFEM_ASSERT( i>=0 && i<size,
907 "Access element " << i << " of array, size = " << size );
908 return data[i];
909}
910
911template <class T>
912inline int Array<T>::Append(const T &el)
913{
914 SetSize(size+1);
915 data[size-1] = el;
916 return size;
917}
918
919template <class T>
920inline int Array<T>::Append(const T *els, int nels)
921{
922 const int old_size = size;
923
924 SetSize(size + nels);
925 for (int i = 0; i < nels; i++)
926 {
927 data[old_size+i] = els[i];
928 }
929 return size;
930}
931
932template <class T>
933inline int Array<T>::Prepend(const T &el)
934{
935 SetSize(size+1);
936 for (int i = size-1; i > 0; i--)
937 {
938 data[i] = data[i-1];
939 }
940 data[0] = el;
941 return size;
942}
943
944template <class T>
945inline T &Array<T>::Last()
946{
947 MFEM_ASSERT(size > 0, "Array size is zero: " << size);
948 return data[size-1];
949}
950
951template <class T>
952inline const T &Array<T>::Last() const
953{
954 MFEM_ASSERT(size > 0, "Array size is zero: " << size);
955 return data[size-1];
956}
957
958template <class T>
959inline int Array<T>::Union(const T &el)
960{
961 int i = 0;
962 while ((i < size) && (data[i] != el)) { i++; }
963 if (i == size)
964 {
965 Append(el);
966 }
967 return i;
968}
969
970template <class T>
971inline int Array<T>::Find(const T &el) const
972{
973 for (int i = 0; i < size; i++)
974 {
975 if (data[i] == el) { return i; }
976 }
977 return -1;
978}
979
980template <class T>
981inline int Array<T>::FindSorted(const T &el) const
982{
983 const T *begin = data, *end = begin + size;
984 const T* first = std::lower_bound(begin, end, el);
985 if (first == end || !(*first == el)) { return -1; }
986 return (int)(first - begin);
987}
988
989template <class T>
990inline void Array<T>::DeleteFirst(const T &el)
991{
992 for (int i = 0; i < size; i++)
993 {
994 if (data[i] == el)
995 {
996 for (i++; i < size; i++)
997 {
998 data[i-1] = data[i];
999 }
1000 size--;
1001 return;
1002 }
1003 }
1004}
1005
1006template <class T>
1007inline void Array<T>::DeleteAt(const Array<int> &indices)
1008{
1009 HostReadWrite();
1010
1011 // Make a copy of the indices, sorted.
1012 Array<int> sorted_indices(indices);
1013 sorted_indices.Sort();
1014
1015 int rm_count = 0;
1016 for (int i = 0; i < size; i++)
1017 {
1018 if (rm_count < sorted_indices.Size() && i == sorted_indices[rm_count])
1019 {
1020 rm_count++;
1021 }
1022 else
1023 {
1024 data[i-rm_count] = data[i]; // shift data rm_count
1025 }
1026 }
1027
1028 // Resize to remove tail
1029 size -= rm_count;
1030}
1031
1032template <class T>
1034{
1035 const bool use_dev = data.UseDevice();
1036 data.Delete(); // calls data.Reset(h_mt) as well
1037 size = 0;
1038 data.UseDevice(use_dev);
1039}
1040
1041template <typename T>
1042inline void Array<T>::Copy(Array &copy) const
1043{
1044 copy.SetSize(Size());
1045 const bool use_dev = UseDevice() || copy.UseDevice();
1046 copy.data.UseDevice(use_dev);
1047 // keep 'copy.data' where it is, unless 'use_dev' is true
1048 if (use_dev) { copy.Write(); }
1049 copy.data.CopyFrom(data, Size());
1050}
1051
1052template <class T>
1053inline void Array<T>::MakeRef(T *data_, int size_, bool own_data)
1054{
1055 data.Delete();
1056 data.Wrap(data_, size_, own_data);
1057 size = size_;
1058}
1059
1060template <class T>
1061inline void Array<T>::MakeRef(T *data_, int size_, MemoryType mt, bool own_data)
1062{
1063 data.Delete();
1064 data.Wrap(data_, size_, mt, own_data);
1065 size = size_;
1066}
1067
1068template <class T>
1069inline void Array<T>::MakeRef(const Array &master)
1070{
1071 data.Delete();
1072 size = master.size;
1073 data.MakeAlias(master.GetMemory(), 0, size);
1074}
1075
1076template <class T>
1078 const Memory<T> &mem, int s, bool own_mem)
1079{
1080 data.Delete();
1081 size = s;
1082 if (own_mem)
1083 {
1084 data = mem;
1085 }
1086 else
1087 {
1088 data.MakeAlias(mem, 0, s);
1089 }
1090}
1091
1092template <class T>
1093inline void Array<T>::GetSubArray(int offset, int sa_size, Array<T> &sa) const
1094{
1095 sa.SetSize(sa_size);
1096 for (int i = 0; i < sa_size; i++)
1097 {
1098 sa[i] = (*this)[offset+i];
1099 }
1100}
1101
1102template <class T>
1103inline void Array<T>::operator=(const T &a)
1104{
1105 for (int i = 0; i < size; i++)
1106 {
1107 data[i] = a;
1108 }
1109}
1110
1111template <class T>
1112inline void Array<T>::Assign(const T *p)
1113{
1114 data.CopyFromHost(p, Size());
1115}
1116
1117
1118template <class T>
1119inline const T &Array2D<T>::operator()(int i, int j) const
1120{
1121 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
1122 "Array2D: invalid access of element (" << i << ',' << j
1123 << ") in array of size (" << array1d.Size()/N << ',' << N
1124 << ")." );
1125 return array1d[i*N+j];
1126}
1127
1128template <class T>
1129inline T &Array2D<T>::operator()(int i, int j)
1130{
1131 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
1132 "Array2D: invalid access of element (" << i << ',' << j
1133 << ") in array of size (" << array1d.Size()/N << ',' << N
1134 << ")." );
1135 return array1d[i*N+j];
1136}
1137
1138template <class T>
1139inline const T *Array2D<T>::operator[](int i) const
1140{
1141 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
1142 "Array2D: invalid access of row " << i << " in array with "
1143 << array1d.Size()/N << " rows.");
1144 return &array1d[i*N];
1145}
1146
1147template <class T>
1149{
1150 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
1151 "Array2D: invalid access of row " << i << " in array with "
1152 << array1d.Size()/N << " rows.");
1153 return &array1d[i*N];
1154}
1155
1156template <class T>
1157inline void Array2D<T>::Swap(Array2D<T> &other)
1158{
1159 mfem::Swap(array1d, other.array1d);
1160 std::swap(M, other.M);
1161 std::swap(N, other.N);
1162}
1163
1164/** @brief Swap of Array2D<T> objects for use with standard library algorithms.
1165 Also, used by mfem::Swap(). */
1166template <typename T>
1168{
1169 a.Swap(b);
1170}
1171
1172
1173template <class T>
1174inline const T &Array3D<T>::operator()(int i, int j, int k) const
1175{
1176 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
1177 && k >= 0 && k < N3,
1178 "Array3D: invalid access of element ("
1179 << i << ',' << j << ',' << k << ") in array of size ("
1180 << array1d.Size() / N2 / N3 << ',' << N2 << ',' << N3 << ").");
1181 return array1d[(i*N2+j)*N3+k];
1182}
1183
1184template <class T>
1185inline T &Array3D<T>::operator()(int i, int j, int k)
1186{
1187 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
1188 && k >= 0 && k < N3,
1189 "Array3D: invalid access of element ("
1190 << i << ',' << j << ',' << k << ") in array of size ("
1191 << array1d.Size() / N2 / N3 << ',' << N2 << ',' << N3 << ").");
1192 return array1d[(i*N2+j)*N3+k];
1193}
1194
1195
1196template<typename T>
1198{
1199 mask = block_size-1;
1200 MFEM_VERIFY(!(block_size & mask), "block_size must be a power of two.");
1201
1202 size = shift = 0;
1203 while ((1 << shift) < block_size) { shift++; }
1204}
1205
1206template<typename T>
1208{
1209 blocks.SetSize(other.blocks.Size());
1210
1211 size = other.size;
1212 shift = other.shift;
1213 mask = other.mask;
1214
1215 int bsize = mask+1;
1216 for (int i = 0; i < blocks.Size(); i++)
1217 {
1218 blocks[i] = (T*) new char[bsize * sizeof(T)];
1219 }
1220
1221 // copy all items
1222 for (int i = 0; i < size; i++)
1223 {
1224 new (&At(i)) T(other[i]);
1225 }
1226}
1227
1228template<typename T>
1230{
1231 int bsize = mask+1;
1232 if (size >= blocks.Size() * bsize)
1233 {
1234 T* new_block = (T*) new char[bsize * sizeof(T)];
1235 blocks.Append(new_block);
1236 }
1237 return size++;
1238}
1239
1240template<typename T>
1242{
1243 int index = Alloc();
1244 new (&At(index)) T();
1245 return index;
1246}
1247
1248template<typename T>
1249int BlockArray<T>::Append(const T &item)
1250{
1251 int index = Alloc();
1252 new (&At(index)) T(item);
1253 return index;
1254}
1255
1256template<typename T>
1258{
1259 mfem::Swap(blocks, other.blocks);
1260 std::swap(size, other.size);
1261 std::swap(shift, other.shift);
1262 std::swap(mask, other.mask);
1263}
1264
1265template<typename T>
1267{
1268 return (mask+1)*sizeof(T)*blocks.Size() + blocks.MemoryUsage();
1269}
1270
1271template<typename T>
1273{
1274 int bsize = size & mask;
1275 for (int i = blocks.Size(); i != 0; )
1276 {
1277 T *block = blocks[--i];
1278 for (int j = bsize; j != 0; )
1279 {
1280 block[--j].~T();
1281 }
1282 delete [] (char*) block;
1283 bsize = mask+1;
1284 }
1285}
1286
1287} // namespace mfem
1288
1289#endif
Dynamic 2D array using row-major layout.
Definition array.hpp:430
void DeleteAll()
Delete all dynamically allocated memory, resetting all dimensions to zero.
Definition array.hpp:523
const T * operator[](int i) const
Definition array.hpp:1139
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
Definition array.hpp:534
int NumCols() const
Definition array.hpp:448
Array2D(int m, int n)
Construct an m x n 2D array.
Definition array.hpp:439
void Swap(Array2D &other)
Swap the contents of the Array2D with other.
Definition array.hpp:1157
Array2D & operator=(const Array2D &)=default
Copy assignment.
T * operator[](int i)
Definition array.hpp:1148
void Copy(Array2D &copy) const
Definition array.hpp:501
Array2D(const Array2D &)=default
void Save(std::ostream &os, int fmt=0) const
Save the Array2D to the stream out using the format fmt.
Definition array.hpp:475
const T & operator()(int i, int j) const
Definition array.hpp:1119
Array2D & operator=(Array2D &&)=default
Move assignment.
const T * GetRow(int i) const
Definition array.hpp:459
void Load(std::istream &in, int fmt=0)
Read an Array2D from the stream in using format fmt.
Definition array.hpp:487
T & operator()(int i, int j)
Definition array.hpp:1129
T * operator()(int i)
Definition array.hpp:457
T * GetRow(int i)
Definition array.hpp:460
int NumRows() const
Definition array.hpp:447
void Print(std::ostream &out=mfem::out, int width=4)
Prints array to stream with width elements per row.
Definition array.cpp:184
void operator=(const T &a)
Set all entries of the array to the provided constant.
Definition array.hpp:504
void GetRow(int i, Array< T > &sa) const
Extract a copy of the i-th row into the Array sa.
Definition array.hpp:463
const T * operator()(int i) const
Definition array.hpp:456
Array2D(Array2D &&)=default
void MakeRef(const Array2D &master)
Make this Array2D a reference to 'master'.
Definition array.hpp:519
void SetSize(int m, int n)
Set the 2D array size to m x n.
Definition array.hpp:445
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition array.hpp:530
void Load(int new_size0, int new_size1, std::istream &in)
Set the Array2D dimensions to new_size0 x new_size1 and read that many entries from the stream in.
Definition array.hpp:498
int GetSize2() const
Get the 3D array size in the second dimension.
Definition array.hpp:564
const T & operator()(int i, int j, int k) const
Definition array.hpp:1174
Array3D(int n1, int n2, int n3)
Construct a 3D array of size n1 x n2 x n3.
Definition array.hpp:549
int GetSize1() const
Get the 3D array size in the first dimension.
Definition array.hpp:557
void SetSize(int n1, int n2, int n3)
Set the 3D array size to n1 x n2 x n3.
Definition array.hpp:553
void operator=(const T &a)
Set all entries of the array to the provided constant.
Definition array.hpp:573
int GetSize3() const
Get the 3D array size in the third dimension.
Definition array.hpp:567
T & operator()(int i, int j, int k)
Definition array.hpp:1185
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
Definition array.hpp:145
T value_type
Type alias for stl.
Definition array.hpp:60
Array(std::initializer_list< CT > values)
Construct an Array from a braced initializer list of convertible type.
Definition array.hpp:773
const T & Last() const
Return the last element in the array.
Definition array.hpp:952
void Sort(Compare cmp)
Sorts the array in ascending order using the supplied comparison function object.
Definition array.hpp:316
void DeleteFirst(const T &el)
Delete the first entry with value == 'el'.
Definition array.hpp:990
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition array.cpp:69
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
Definition array.cpp:54
int FindSorted(const T &el) const
Do bisection search for 'el' in a sorted array; return -1 if not found.
Definition array.hpp:981
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
Definition array.hpp:385
void MakeRef(const Array &master)
Make this Array a reference to 'master'.
Definition array.hpp:1069
void GetSubArray(int offset, int sa_size, Array< T > &sa) const
Copy sub array starting from offset out to the provided sa.
Definition array.hpp:1093
int size
Size of the array.
Definition array.hpp:53
Array< T > & operator=(Array< T > &&src)
Move assignment operator.
Definition array.hpp:117
int Union(const T &el)
Append element when it is not yet in the array, return index.
Definition array.hpp:959
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
Definition array.hpp:312
T & operator[](int i)
Reference access to the ith element.
Definition array.hpp:896
void MakeDataOwner() const
Make the Array own the data.
Definition array.hpp:163
bool IsConstant() const
Return true if all entries of the array are the same.
Definition array.cpp:158
void Assign(const T *)
Copy data from a pointer. 'Size()' elements are copied.
Definition array.hpp:1112
void push_back(const T &el)
STL-like push_back. Append element 'el' to array, resize if necessary.
Definition array.hpp:197
void CopyFrom(const U *src)
Copy from src into this array. Copies enough entries to fill the Capacity size of this array....
Definition array.hpp:358
Array< T > & operator=(const Array< T > &src)
Copy assignment operator: deep copy from 'src'.
Definition array.hpp:114
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:397
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
Definition array.hpp:184
void StealData(T **p)
Changes the ownership of the data.
Definition array.hpp:157
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:840
int Prepend(const T &el)
Prepend an 'el' to the array, resize if necessary.
Definition array.hpp:933
bool IsEmpty() const
Does the Array have Size zero.
Definition array.hpp:330
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
Definition array.cpp:86
void LoseData()
NULL-ifies the data.
Definition array.hpp:160
int Size() const
Return the logical size of the array.
Definition array.hpp:166
const T * begin() const
STL-like begin. Returns const pointer to the first element of the array.
Definition array.hpp:372
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
Definition array.cpp:104
Memory< T > data
Pointer to data.
Definition array.hpp:51
bool UseDevice() const
Return the device flag of the Memory object used by the Array.
Definition array.hpp:151
const T * end() const
STL-like end. Returns const pointer after the last element of the array.
Definition array.hpp:375
void operator=(const T &a)
Set all entries of the array to the provided constant.
Definition array.hpp:1103
Array(MemoryType mt)
Creates an empty array with a given MemoryType.
Definition array.hpp:68
int Append(const T *els, int nels)
Append another array to this array, resize if necessary.
Definition array.hpp:920
int IsSorted() const
Return 1 if the array is sorted from lowest to highest. Otherwise return 0.
Definition array.cpp:141
int Append(const Array< T > &els)
Append another array to this array, resize if necessary.
Definition array.hpp:203
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
Definition array.hpp:1053
Array(int asize, MemoryType mt)
Creates array of asize elements with a given MemoryType.
Definition array.hpp:75
Array(const Array< CT > &src)
Copy constructor (deep copy) from 'src', an Array of convertible type.
Definition array.hpp:763
void DeleteAll()
Delete the whole array.
Definition array.hpp:1033
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:389
int Find(const T &el) const
Return the first index where 'el' is found; return -1 if not found.
Definition array.hpp:971
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:912
T * GetData()
Returns the data.
Definition array.hpp:140
const T * GetData() const
Returns the data.
Definition array.hpp:142
const Memory< T > & GetMemory() const
Return a reference to the Memory object used by the Array, const version.
Definition array.hpp:148
void Save(std::ostream &out, int fmt=0) const
Save the Array to the stream out using the format fmt. The format fmt can be:
Definition array.cpp:41
void Copy(Array &copy) const
Create a copy of the internal array to the provided copy.
Definition array.hpp:1042
Array(Array< T > &&src)
Move constructor ("steals" data from 'src')
Definition array.hpp:105
Array(const Array &src)
Copy constructor: deep copy from src.
Definition array.hpp:754
void Permute(const I &indices)
Definition array.hpp:274
bool OwnsData() const
Return true if the data will be deleted by the Array.
Definition array.hpp:154
void Unique()
Removes duplicities from a sorted array. This requires operator== to be defined for T.
Definition array.hpp:320
void Permute(I &&indices)
Permute the array using the provided indices. Sorts the indices variable in the process,...
Definition array.hpp:815
T & reference
Type alias for stl.
Definition array.hpp:61
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:381
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
Definition array.hpp:401
void ShrinkToFit()
Reduces the capacity of the array to exactly match the current size.
Definition array.hpp:803
T * end()
STL-like end. Returns pointer after the last element of the array.
Definition array.hpp:369
~Array()
Destructor.
Definition array.hpp:111
const T & const_reference
Type alias for stl.
Definition array.hpp:62
void Abs()
Replace each entry of the array with its absolute value.
Definition array.cpp:115
Array()
Creates an empty array.
Definition array.hpp:65
Array(T *data_, int asize, bool own_data=false)
Creates array using an externally allocated host pointer data_ to asize elements. If own_data is true...
Definition array.hpp:84
T * begin()
STL-like begin. Returns pointer to the first element of the array.
Definition array.hpp:366
void Print(std::ostream &out=mfem::out, int width=4) const
Prints array to stream with width elements per row.
Definition array.cpp:24
const T & operator[](int i) const
Const reference access to the ith element.
Definition array.hpp:904
Array & operator=(const Array< CT > &src)
Assignment operator (deep copy) from src, an Array of convertible type.
std::size_t MemoryUsage() const
Returns the number of bytes allocated for the array including any reserve.
Definition array.hpp:378
Array(const CT(&values)[N])
Construct an Array from a C-style array of static length.
Definition array.hpp:779
void NewMemoryAndSize(const Memory< T > &mem, int s, bool own_mem)
Reset the Array to use the given external Memory mem and size s.
Definition array.hpp:1077
int Capacity() const
Definition array.hpp:181
void MakeRef(T *data_, int size, MemoryType mt, bool own_data)
Make this Array a reference to a pointer.
Definition array.hpp:1061
Array(int asize)
Creates array of asize elements.
Definition array.hpp:71
void CopyTo(U *dest)
STL-like copyTo dest from begin to end.
Definition array.hpp:352
void DeleteAt(const Array< int > &indices)
Delete entries at indices, and resize.
Definition array.hpp:1007
void SetSize(int nsize, MemoryType mt)
Resize the array to size nsize using MemoryType mt. Note that unlike the other versions of SetSize(),...
Definition array.hpp:869
void GrowSize(int minsize)
Definition array.hpp:792
T Sum() const
Return the sum of all the array entries using the '+'' operator for class 'T'.
Definition array.cpp:129
void Swap(Array &other)
Swap the contents of the Array with other.
Definition array.hpp:785
void DeleteLast()
Delete the last entry of the array.
Definition array.hpp:224
void SetSize(int nsize, const T &initval)
Same as SetSize(int) plus initialize new entries with 'initval'.
Definition array.hpp:851
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
Definition array.hpp:393
T & Last()
Return the last element in the array.
Definition array.hpp:945
void Load(int new_size, std::istream &in)
Set the Array size to new_size and read that many entries from the stream in.
Definition array.hpp:300
const_iterator(const BlockArray *a)
Definition array.hpp:701
const_iterator & operator++()
Definition array.hpp:704
iterator_base< const BlockArray, const T > base
Definition array.hpp:697
bool operator!=(const const_iterator &other) const
Definition array.hpp:707
bool operator==(const const_iterator &other) const
Definition array.hpp:706
bool operator==(const iterator &other) const
Definition array.hpp:689
iterator(BlockArray *a)
Definition array.hpp:684
iterator & operator++()
Definition array.hpp:687
bool operator!=(const iterator &other) const
Definition array.hpp:690
iterator_base< BlockArray, T > base
Definition array.hpp:680
void DeleteAll()
Destroy all items, set size to zero.
Definition array.hpp:622
Array< T * > blocks
Definition array.hpp:720
BlockArray(const BlockArray< T > &other)
Definition array.hpp:1207
const T & At(int index) const
Definition array.hpp:605
int Capacity() const
Return the current capacity of the BlockArray.
Definition array.hpp:619
iterator begin()
Definition array.hpp:710
std::size_t MemoryUsage() const
Definition array.hpp:1266
const_iterator cend() const
Definition array.hpp:717
BlockArray & operator=(const BlockArray &)=delete
T & At(int index)
Access item of the array.
Definition array.hpp:600
const T & operator[](int index) const
Definition array.hpp:613
void CheckIndex(int index) const
Definition array.hpp:725
void Swap(BlockArray< T > &other)
Definition array.hpp:1257
iterator end()
Definition array.hpp:711
int Append()
Allocate and construct a new item in the array, return its index.
Definition array.hpp:1241
const_iterator cbegin() const
Definition array.hpp:715
BlockArray & operator=(BlockArray< T > &&other)=default
const_iterator begin() const
Definition array.hpp:712
const_iterator end() const
Definition array.hpp:713
T & operator[](int index)
Access item of the array.
Definition array.hpp:612
int Append(const T &item)
Allocate and copy-construct a new item in the array, return its index.
Definition array.hpp:1249
int Size() const
Return the number of items actually stored.
Definition array.hpp:616
BlockArray(BlockArray< T > &&other)=default
BlockArray(int block_size=16 *1024)
Definition array.hpp:1197
Class used by MFEM to store pointers to host and/or device memory.
int Capacity() const
Return the size of the allocated memory.
void CopyFromHost(const T *src, int size)
Copy size entries from the host pointer src to *this.
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.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
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...
int index(int i, int j, int nx, int ny)
Definition life.cpp:236
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
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
T * HostReadWrite(Memory< T > &mem, int size)
Shortcut to ReadWrite(Memory<T> &mem, int size, false)
Definition device.hpp:389
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
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
bool operator!=(const Array< T > &LHS, const Array< T > &RHS)
Definition array.hpp:417
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
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
Definition array.hpp:406
const T & AsConst(const T &a)
Utility function similar to std::as_const in c++17.
Definition array.hpp:424
MemoryType
Memory types supported by MFEM.
real_t p(const Vector &x, real_t t)