netxsimdg
Loading...
Searching...
No Matches
ModelArray.hpp
1
8#ifndef MODELARRAY_HPP
9#define MODELARRAY_HPP
10
11#include <Eigen/Core>
12#include <cstddef>
13#include <map>
14#include <string>
15#include <utility>
16#include <vector>
17
18namespace Nextsim {
19
20/*
21 * Set the storage order to row major. This matches with DGVector when there is
22 * more than one DG component. If there is only one DG component (the finite
23 * element component), then the order of the data in the buffer is the same,
24 * and data can be safely transferred between the buffers underlying the two
25 * types. The physics code will never directly touch the spatially varying
26 * components, so the choice of storage order should not matter.
27 */
28const static Eigen::StorageOptions majority = Eigen::RowMajor;
29
48public:
49 // Forward defines make Eclipse less red and squiggly
50 enum class Type;
51 enum class Dimension;
52
53#include "include/ModelArrayDetails.hpp"
54
55 static const int N_DEFINED_DIMENSIONS = static_cast<int>(Dimension::COUNT);
56
58 std::string name;
59 size_t length;
60 };
61 typedef std::map<Type, std::vector<Dimension>> TypeDimensions;
62
64 static TypeDimensions typeDimensions;
66 static std::map<Dimension, DimensionSpec> definedDimensions;
68 static const std::map<Type, std::string> typeNames;
69 // The dimension that defines the components of each ModelArray type, if any
70 static const std::map<Type, Dimension> componentMap;
71
72 typedef Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, majority> DataType;
73
74 typedef DataType::RowXpr Component;
75 typedef DataType::ConstRowXpr ConstComponent;
76
80 ModelArray();
87 ModelArray(const Type type);
89 ModelArray(const ModelArray&);
90 virtual ~ModelArray() {};
91
99 ModelArray& operator=(const double& val);
100
101 // ModelArray arithmetic
104 {
105 m_data += b.m_data;
106 return *this;
107 }
110 {
111 m_data -= b.m_data;
112 return *this;
113 }
116 {
117 m_data *= b.m_data;
118 return *this;
119 }
122 {
123 m_data /= b.m_data;
124 return *this;
125 }
126
129 {
130 m_data += b;
131 return *this;
132 }
135 {
136 m_data -= b;
137 return *this;
138 }
141 {
142 m_data *= b;
143 return *this;
144 }
147 {
148 m_data /= b;
149 return *this;
150 }
151
154 ModelArray operator+(const ModelArray&) const;
157 ModelArray operator-(const ModelArray&) const;
160 ModelArray operator*(const ModelArray&) const;
163 ModelArray operator/(const ModelArray&) const;
164 // Returns a ModelArray containing the element-wise negation of this.
165 ModelArray operator-() const;
166
168 ModelArray operator+(const double&) const;
170 ModelArray operator-(const double&) const;
172 ModelArray operator*(const double&) const;
174 ModelArray operator/(const double&) const;
175
180 ModelArray max(double max) const;
185 ModelArray min(double min) const;
190 ModelArray max(const ModelArray& maxArr) const;
195 ModelArray min(const ModelArray& minArr) const;
196
201 ModelArray& clampAbove(double max);
206 ModelArray& clampBelow(double min);
211 ModelArray& clampAbove(const ModelArray& maxArr);
216 ModelArray& clampBelow(const ModelArray& minArr);
217
218 typedef std::vector<size_t> MultiDim;
219
221 size_t nDimensions() const { return nDimensions(type); }
223 static size_t nDimensions(Type type) { return m_dims.at(type).size(); }
225 const MultiDim& dimensions() const { return dimensions(type); }
227 static const MultiDim& dimensions(Type type) { return m_dims.at(type); }
229 size_t size() const { return size(type); }
231 static size_t size(Type type) { return m_sz.at(type); }
233 size_t trueSize() const { return m_data.rows(); }
234
236 const double* getData() const { return m_data.data(); }
237
239 const DataType& data() const { return m_data; }
241 Type getType() const { return type; }
242
250 static void setDimensions(Type, const MultiDim&);
260 void setDimensions(const MultiDim& dims)
261 {
262 setDimensions(type, dims);
263 resize();
264 }
265
273 static void setDimension(Dimension dim, size_t length);
274
277 void resize()
278 {
279 if (size() != trueSize()) {
280 if (hasDoF(type)) {
281 m_data.resize(m_sz.at(type), definedDimensions.at(componentMap.at(type)).length);
282 } else {
283 m_data.resize(m_sz.at(type), Eigen::NoChange);
284 }
285 }
286 }
287
293 void setData(double value);
304 void setData(const double* pData);
311 void setData(const DataType& data);
322 void setData(const ModelArray& source);
323
324private:
325 // Fast special case for 1-d indexing
326 template <typename T, typename I> static inline T indexr(const T* dims, I first)
327 {
328 return static_cast<T>(first);
329 }
330
331 // Fast special case for 2-d indexing
332 template <typename T, typename I> static inline T indexr(const T* dims, I first, I second)
333 {
334 return first + second * dims[0];
335 }
336
337 // Indices as separate function parameters
338 template <typename T, typename I, typename... Args>
339 static inline T indexr(const T* dims, I first, Args... args)
340 {
341 std::initializer_list<I> loc { first, args... };
342 return indexrHelper(dims, loc);
343 }
344
345 // Indices as a Dimensions object
346 template <typename T> static T indexr(const T* dims, const ModelArray::MultiDim& loc)
347 {
348 return indexrHelper(dims, loc);
349 }
350
351 // Generic index generator that will work on any container
352 template <typename T, typename C> static T indexrHelper(const T* dims, const C& loc)
353 {
354 size_t ndims = loc.size();
355 T stride = 1;
356 T ii = 0;
357 auto iloc = begin(loc);
358 for (size_t dim = 0; dim < ndims; ++dim) {
359 ii += stride * (*iloc++);
360 stride *= dims[dim];
361 }
362 return ii;
363 }
364
365public:
375 const double& operator[](size_t i) const { return m_data(i, 0); }
387 const double& operator[](const MultiDim& dims) const;
388
392 template <typename... Args> const double& operator()(Args... args) const
393 {
394 return (*this)[indexr(dimensions().data(), args...)];
395 }
396
407 double& operator[](size_t i) { return const_cast<double&>(std::as_const(*this)(i)); }
419 double& operator[](const MultiDim&);
423 template <typename... Args> double& operator()(Args... args)
424 {
425 return const_cast<double&>(std::as_const(*this)(args...));
426 }
427
433 static void setNComponents(std::map<Type, size_t> cMap);
434
441 static void setNComponents(Type type, size_t nComp)
442 {
443 if (hasDoF(type)) {
444 definedDimensions.at(componentMap.at(type)).length = nComp;
445 }
446 }
447
453 inline void setNComponents(size_t nComp) { setNComponents(type, nComp); }
454
461 Component components(size_t i) { return m_data.row(i); }
462
463 const ConstComponent components(size_t i) const { return m_data.row(i); }
464
470 Component components(const MultiDim& loc);
471 const ConstComponent components(const MultiDim& loc) const;
472
482 double& zIndexAndLayer(size_t hIndex, size_t layer)
483 {
484 return this->operator[](zLayerIndex(hIndex, layer));
485 }
495 const double& zIndexAndLayer(size_t hIndex, size_t layer) const
496 {
497 return this->operator[](zLayerIndex(hIndex, layer));
498 }
499
505 size_t indexFromLocation(const MultiDim& loc) const { return indexFromLocation(type, loc); }
506
513 static size_t indexFromLocation(Type type, const MultiDim& loc);
514
520 MultiDim locationFromIndex(size_t index) const { return locationFromIndex(type, index); }
521
528 static MultiDim locationFromIndex(Type type, size_t index);
529
532 inline size_t nComponents() const { return nComponents(type); }
535 inline static size_t nComponents(const Type type)
536 {
537 return (hasDoF(type)) ? definedDimensions.at(componentMap.at(type)).length : 1;
538 }
541 inline bool hasDoF() const { return hasDoF(type); }
544 static bool hasDoF(const Type type);
545
546protected:
547 Type type;
548
558 size_t zLayerIndex(size_t hIndex, size_t layer) const
559 {
560 return hIndex + layer * dimensions()[0] * dimensions()[1];
561 }
562
563private:
564 static bool areMapsInvalid;
565 static void validateMaps();
566 class SizeMap {
567 public:
568 SizeMap();
569 size_t& at(const Type& type) { return m_sizes.at(type); }
570 const size_t& at(const Type& type) const { return m_sizes.at(type); }
571
572 size_t& operator[](const Type& type) { return m_sizes[type]; }
573 size_t& operator[](Type&& type) { return m_sizes[type]; }
574
575 size_t size() const noexcept { return m_sizes.size(); }
576
577 void validate();
578
579 protected:
580 std::map<Type, size_t> m_sizes;
581 };
582 static SizeMap m_sz;
583
584 class DimensionMap {
585 public:
586 DimensionMap();
587 MultiDim& at(const Type& type) { return m_dimensions.at(type); }
588 const MultiDim& at(const Type& type) const { return m_dimensions.at(type); }
589
590 MultiDim& operator[](const Type& type) { return m_dimensions[type]; }
591 MultiDim& operator[](Type&& type) { return m_dimensions[type]; }
592
593 size_t size() const noexcept { return m_dimensions.size(); }
594
595 void validate();
596
597 private:
598 std::map<Type, MultiDim> m_dimensions;
599 };
600 static DimensionMap m_dims;
601 DataType m_data;
602};
603
604#include "include/ModelArrayTypedefs.hpp"
605
606// ModelArray arithmetic with doubles
607ModelArray operator+(const double&, const ModelArray&);
608ModelArray operator-(const double&, const ModelArray&);
609ModelArray operator*(const double&, const ModelArray&);
610ModelArray operator/(const double&, const ModelArray&);
611} /* namespace Nextsim */
612
613#endif /* MODELARRAY_HPP */
A class that holds the array data for the model.
const double & operator[](size_t i) const
Returns the data at the specified one dimensional index.
Component components(size_t i)
Accesses the full Discontinuous Galerkin coefficient vector at the indexed location.
double & operator[](size_t i)
Returns the data at the specified one dimensional index.
ModelArray & operator+=(double b)
In place addition of a double.
size_t trueSize() const
Returns the size of the data array of this object.
static TypeDimensions typeDimensions
The dimensions that make up each defined type. Defined in ModelArrayDetails.cpp.
static size_t size(Type type)
Returns the total number of elements of the specified type of ModelArray.
ModelArray & operator+=(const ModelArray &b)
In place addition of another ModelArray.
bool hasDoF() const
Returns whether this type of ModelArray has additional discontinuous Galerkin components.
size_t indexFromLocation(const MultiDim &loc) const
Returns the index for a given set of multi-dimensional location for this array's type.
static const MultiDim & dimensions(Type type)
Returns a vector<size_t> of the size of each dimension of the specified type of ModelArray.
double & zIndexAndLayer(size_t hIndex, size_t layer)
Special access function for ZFields.
const MultiDim & dimensions() const
Returns a vector<size_t> of the size of each dimension of this type of ModelArray.
ModelArray & clampBelow(double min)
Clamps the values in the array to the given minimum.
double & operator()(Args... args)
Returns the specified point from a ModelArray.
ModelArray & operator/=(double b)
In place division by a double.
ModelArray operator*(const ModelArray &) const
Returns a ModelArray containing the per-element product of the object and the provided ModelArray.
static void setNComponents(Type type, size_t nComp)
Sets the number of components for a single D/CG array type.
ModelArray & operator*=(double b)
In place multiplication by a double.
ModelArray min(double min) const
Calculates element-wise minimum of the data and the given scalar value.
ModelArray & operator-=(const ModelArray &b)
In place subtraction of another ModelArray.
ModelArray & operator/=(const ModelArray &b)
In place division by another ModelArray.
ModelArray & operator=(const ModelArray &)
Copy assignment operator.
ModelArray operator+(const ModelArray &) const
Returns a ModelArray containing the per-element sum of the object and the provided ModelArray.
const double & zIndexAndLayer(size_t hIndex, size_t layer) const
Special access function for ZFields, const version.
static size_t nDimensions(Type type)
Returns the number of dimensions of the specified type of ModelArray.
ModelArray & clampAbove(double max)
Clamps the values in the array to the given maximum.
static void setDimensions(Type, const MultiDim &)
Sets the number and size of the dimensions of a specified type of ModelArray.
static void setDimension(Dimension dim, size_t length)
Sets the length of an individual dimension before propagating it to the defined array types.
Type getType() const
Returns the (enum of) the ModelArray::Type of this.
void setData(double value)
Sets the value of every element in the object to the provided value.
void setDimensions(const MultiDim &dims)
Sets the number and size of the dimensions of this type of ModelArray.
void resize()
Conditionally updates the size of the object data buffer to match the class specification.
ModelArray operator/(const ModelArray &) const
Returns a ModelArray containing the per-element ratio between the object and the provided ModelArray.
const DataType & data() const
Returns a const reference to the Eigen data.
size_t nComponents() const
Returns the number of discontinuous Galerkin components held in this type of ModelArray.
size_t nDimensions() const
Returns the number of dimensions of this type of ModelArray.
const double & operator()(Args... args) const
Returns the data at the given set of indices.
size_t zLayerIndex(size_t hIndex, size_t layer) const
Special access function for ZFields, common implementation version.
ModelArray & operator*=(const ModelArray &b)
In place multiplication by another ModelArray.
const double * getData() const
Returns a read-only pointer to the underlying data buffer.
void setNComponents(size_t nComp)
Sets the number of components for this array's type.
MultiDim locationFromIndex(size_t index) const
Returns the multi-dimensional location for a given index for this array's type.
ModelArray max(double max) const
Calculates element-wise maximum of the data and the given scalar value.
size_t size() const
Returns the total number of elements of this type of ModelArray.
static size_t nComponents(const Type type)
Returns the number of discontinuous Galerkin components held in the specified type of ModelArray.
static std::map< Dimension, DimensionSpec > definedDimensions
The name and length of each dimension that is defined.
static const std::map< Type, std::string > typeNames
The name of each type of ModelArray.
static void setNComponents(std::map< Type, size_t > cMap)
Sets the number of components for DG & CG array types.
ModelArray & operator-=(double b)
In place subtraction of a double.