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