MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
dgcartesiansurfacecollector.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef MAIA_DGSURFACECOLLECTOR_H
8#define MAIA_DGSURFACECOLLECTOR_H
9
10// The following macro enables the "Structure-of-Arrays" memory layout for multi-dimensional node
11// variables. This might be beneficial for GPU computations. Default is "Array-of-Structures".
12// Examples (for nodes nN with four children cM each)
13// Array-of-Structures (AOS): n0c0, n0c1, n0c2, n0c3, n1c0, n1c1, n1c2, n1c3, n2c0, n2c1, ...
14// Structure-of-Arrays (SOA): n0c0, n1c0, n2c0, n3c0, ..., n0c1, n1c1, n2c1, n3c1, ..., n0c2, ...
15// #define DGCOLLECTOR_SOA_MEMORY_LAYOUT
16
17// The macro 'DGCOLLECTOR_SANITY_CHECKS_ACCESSORS' enables (potentially very expensive) sanity
18// checks
19// for all accessors. It is enabled for build type "extra_debug".
20#ifdef MAIA_EXTRA_DEBUG
21#define DGCOLLECTOR_SANITY_CHECKS_ACCESSORS
22#endif
23
24// Sanity-checking macros for accessors
25#if defined(DGCOLLECTOR_SANITY_CHECKS_ACCESSORS) || defined(MAIA_ASSERT_ACCESSORS)
26#define ENSURE_VALID_ID_ACCESSOR(id) \
27 do { \
28 MAIA_CONTAINER_ENSURE_VALID_ID(id); \
29 } while(false)
30#define ENSURE_VALID_SIDE_ACCESSOR(side) \
31 do { \
32 MAIA_CONTAINER_ENSURE(side >= 0 && side < 2, "side " + std::to_string(side) + " out-of-bounds [0, 2)", AT_); \
33 } while(false)
34#define ENSURE_VALID_DIR_ACCESSOR(orientation) \
35 do { \
36 MAIA_CONTAINER_ENSURE( \
37 orientation >= 0 && orientation < nDim, \
38 "orientation " + std::to_string(orientation) + " out-of-bounds [0, " + std::to_string(nDim) + ")", AT_); \
39 } while(false)
40#else
41#define ENSURE_VALID_ID_ACCESSOR(id) \
42 do { \
43 } while(false)
44#define ENSURE_VALID_SIDE_ACCESSOR(side) \
45 do { \
46 } while(false)
47#define ENSURE_VALID_DIR_ACCESSOR(orientation) \
48 do { \
49 } while(false)
50#endif
51
53namespace maia {
54namespace dg {
55namespace collector {
56
58template <MInt nDim, class SysEqn>
59class SurfaceCollector : public maia::container::Container<SurfaceCollector<nDim, SysEqn>, Invalid> {
60 // Necessary for CRTP
61 friend class maia::container::Container<SurfaceCollector<nDim, SysEqn>, Invalid>;
62
63 // Make base class functions known to use without this pointer
66 template <class T>
67 using Storage = typename Base::template Storage<T>;
68
69 public:
70 // Types
71 template <class T>
73
74 // Constructor
76 constexpr SurfaceCollector() = default;
77
78 // Ensure that base class method is found when called from outside
79 using Base::copyData;
81 using Base::reset;
82
83 // Accessor
84 MInt& orientation(const MInt srfcId);
85 MInt orientation(const MInt srfcId) const;
86 MInt& fineCellId(const MInt srfcId);
87 MInt fineCellId(const MInt srfcId) const;
88 MInt& internalSideId(const MInt srfcId);
89 MInt internalSideId(const MInt srfcId) const;
90 MInt& polyDeg(const MInt srfcId);
91 MInt polyDeg(const MInt srfcId) const;
92 MInt& noNodes1D(const MInt srfcId);
93 MInt noNodes1D(const MInt srfcId) const;
94 MInt noNodesXD(const MInt srfcId) const;
95 MLong& globalId(const MInt srfcId);
96 MLong globalId(const MInt srfcId) const;
97 MFloat& coords(const MInt srfcId, const MInt dir);
98 MFloat coords(const MInt srfcId, const MInt dir) const;
99 MFloat& nodeCoords(const MInt srfcId);
100 MFloat nodeCoords(const MInt srfcId) const;
101 MFloat& flux(const MInt srfcId);
102 MFloat flux(const MInt srfcId) const;
103 MInt& nghbrElementIds(const MInt srfcId, const MInt side);
104 MInt nghbrElementIds(const MInt srfcId, const MInt side) const;
105 MFloat& variables(const MInt srfcId, const MInt side);
106 MFloat& variables(const MInt srfcId, const MInt side) const;
107 MFloat& nodeVars(const MInt srfcId, const MInt side);
108 MFloat& nodeVars(const MInt srfcId, const MInt side) const;
109
111 MInt maxPolyDeg() const { return m_maxPolyDeg; }
112
113 // Set maximum polynomial degree
114 void maxPolyDeg(const MInt maxPolyDeg_) { m_maxPolyDeg = maxPolyDeg_; };
115
117 MInt maxNoNodes1D() const { return m_maxNoNodes1D; }
118
119 // Set maximum number of nodes
120 void maxNoNodes1D(const MInt maxNoNodes1D_) {
121 m_maxNoNodes1D = maxNoNodes1D_;
123 };
124
126 MInt maxNoNodesXD() const { return m_maxNoNodesXD; }
127
128 // Set number of node variables
129 void noNodeVars(const MInt noNodeVars_) { m_noNodeVars = noNodeVars_; };
130
132 constexpr MInt noNodeVars() const { return m_noNodeVars; }
133
134 constexpr MInt noValuesVariables() const { return maxNoNodesXD() * SysEqn::noVars(); }
135
136 constexpr MInt noValuesNodeVars() const { return maxNoNodesXD() * noNodeVars(); }
137
138 constexpr MInt noValuesNodeCoordinates() const { return maxNoNodesXD() * nDim; }
139
140 constexpr MInt noValuesFlux() const { return maxNoNodesXD() * SysEqn::noVars(); }
141
142 private:
143 // Methods required by base class for CRTP
144 void reset();
145 void invalidate(const MInt begin, const MInt end);
146 template <class Functor, class T>
147 void rawCopyGeneric(Functor&& c, const T& source, const MInt begin, const MInt end, const MInt destination);
148
152
153 // Number of node variables
155
156 // Data containers
163
164 // Note: The following global id seemed to be a good idea when it was
165 // introduced in July 2013. There are certain advantages of having a
166 // globally unique surface id available permanently, especially for
167 // debugging purposes. The disadvantage, however, is of course thei
168 // increased storage requirements. Should this not be used more
169 // extensively in the future (or only during initialization (as it is
170 // now) where one could just recalculate the id), this should be removed
171 // again.
172 // Note: The global surface id is calculated as the lower global cell id of
173 // both adjacent cells (if existing), which is multiplied by 2*nDim and
174 // then added to the direction id (0 = -x, 1 = +x, 2 = -y, etc.)
175 // relative to that cell.
176 // Example: global cell ids: 24, 13; nDim: 2; directionId: 2;
177 // global surface id: 54
179
185};
186
187
189template <MInt nDim, class SysEqn>
191// Prevent accidental compilation without support for SoA layout
192#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
193#error Missing implementation for structure-of-arrays memory layout.
194#endif
195 ENSURE_VALID_ID_ACCESSOR(srfcId);
196 return m_orientation[srfcId];
197}
199template <MInt nDim, class SysEqn>
201// Prevent accidental compilation without support for SoA layout
202#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
203#error Missing implementation for structure-of-arrays memory layout.
204#endif
205 ENSURE_VALID_ID_ACCESSOR(srfcId);
206 return m_orientation[srfcId];
207}
208
209
211template <MInt nDim, class SysEqn>
213// Prevent accidental compilation without support for SoA layout
214#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
215#error Missing implementation for structure-of-arrays memory layout.
216#endif
217 ENSURE_VALID_ID_ACCESSOR(srfcId);
218 return m_fineCellId[srfcId];
219}
221template <MInt nDim, class SysEqn>
223// Prevent accidental compilation without support for SoA layout
224#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
225#error Missing implementation for structure-of-arrays memory layout.
226#endif
227 ENSURE_VALID_ID_ACCESSOR(srfcId);
228 return m_fineCellId[srfcId];
229}
230
231
233template <MInt nDim, class SysEqn>
235// Prevent accidental compilation without support for SoA layout
236#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
237#error Missing implementation for structure-of-arrays memory layout.
238#endif
239 ENSURE_VALID_ID_ACCESSOR(srfcId);
240 return m_internalSideId[srfcId];
241}
243template <MInt nDim, class SysEqn>
245// Prevent accidental compilation without support for SoA layout
246#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
247#error Missing implementation for structure-of-arrays memory layout.
248#endif
249 ENSURE_VALID_ID_ACCESSOR(srfcId);
250 return m_internalSideId[srfcId];
251}
252
253
255template <MInt nDim, class SysEqn>
257// Prevent accidental compilation without support for SoA layout
258#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
259#error Missing implementation for structure-of-arrays memory layout.
260#endif
261 ENSURE_VALID_ID_ACCESSOR(srfcId);
262 return m_polyDeg[srfcId];
263}
265template <MInt nDim, class SysEqn>
267// Prevent accidental compilation without support for SoA layout
268#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
269#error Missing implementation for structure-of-arrays memory layout.
270#endif
271 ENSURE_VALID_ID_ACCESSOR(srfcId);
272 return m_polyDeg[srfcId];
273}
274
276template <MInt nDim, class SysEqn>
278// Prevent accidental compilation without support for SoA layout
279#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
280#error Missing implementation for structure-of-arrays memory layout.
281#endif
282 ENSURE_VALID_ID_ACCESSOR(srfcId);
283 return m_noNodes1D[srfcId];
284}
286template <MInt nDim, class SysEqn>
288// Prevent accidental compilation without support for SoA layout
289#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
290#error Missing implementation for structure-of-arrays memory layout.
291#endif
292 ENSURE_VALID_ID_ACCESSOR(srfcId);
293 return m_noNodes1D[srfcId];
294}
296template <MInt nDim, class SysEqn>
298// Prevent accidental compilation without support for SoA layout
299#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
300#error Missing implementation for structure-of-arrays memory layout.
301#endif
302 ENSURE_VALID_ID_ACCESSOR(srfcId);
303 return ipow(m_noNodes1D[srfcId], nDim - 1);
304}
305
307template <MInt nDim, class SysEqn>
309// Prevent accidental compilation without support for SoA layout
310#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
311#error Missing implementation for structure-of-arrays memory layout.
312#endif
313 ENSURE_VALID_ID_ACCESSOR(srfcId);
314 return m_globalId[srfcId];
315}
317template <MInt nDim, class SysEqn>
319// Prevent accidental compilation without support for SoA layout
320#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
321#error Missing implementation for structure-of-arrays memory layout.
322#endif
323 ENSURE_VALID_ID_ACCESSOR(srfcId);
324 return m_globalId[srfcId];
325}
326
327
329template <MInt nDim, class SysEqn>
331// Prevent accidental compilation without support for SoA layout
332#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
333#error Missing implementation for structure-of-arrays memory layout.
334#endif
335 ENSURE_VALID_ID_ACCESSOR(srfcId);
336 ENSURE_VALID_DIR_ACCESSOR(dir);
337 return m_coordinates[srfcId * nDim + dir];
338}
340template <MInt nDim, class SysEqn>
342// Prevent accidental compilation without support for SoA layout
343#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
344#error Missing implementation for structure-of-arrays memory layout.
345#endif
346 ENSURE_VALID_ID_ACCESSOR(srfcId);
347 ENSURE_VALID_DIR_ACCESSOR(dir);
348 return m_coordinates[srfcId * nDim + dir];
349}
350
351
353template <MInt nDim, class SysEqn>
355// Prevent accidental compilation without support for SoA layout
356#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
357#error Missing implementation for structure-of-arrays memory layout.
358#endif
359 ENSURE_VALID_ID_ACCESSOR(srfcId);
360 return m_nodeCoordinates[srfcId * noValuesNodeCoordinates()];
361}
363template <MInt nDim, class SysEqn>
365// Prevent accidental compilation without support for SoA layout
366#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
367#error Missing implementation for structure-of-arrays memory layout.
368#endif
369 ENSURE_VALID_ID_ACCESSOR(srfcId);
370 return m_nodeCoordinates[srfcId * noValuesNodeCoordinates()];
371}
372
373
375template <MInt nDim, class SysEqn>
377// Prevent accidental compilation without support for SoA layout
378#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
379#error Missing implementation for structure-of-arrays memory layout.
380#endif
381 ENSURE_VALID_ID_ACCESSOR(srfcId);
382 return m_flux[srfcId * noValuesFlux()];
383}
385template <MInt nDim, class SysEqn>
387// Prevent accidental compilation without support for SoA layout
388#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
389#error Missing implementation for structure-of-arrays memory layout.
390#endif
391 ENSURE_VALID_ID_ACCESSOR(srfcId);
392 return m_flux[srfcId * noValuesFlux()];
393}
394
395
397template <MInt nDim, class SysEqn>
399// Prevent accidental compilation without support for SoA layout
400#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
401#error Missing implementation for structure-of-arrays memory layout.
402#endif
403 ENSURE_VALID_ID_ACCESSOR(srfcId);
404 ENSURE_VALID_SIDE_ACCESSOR(side);
405 return m_nghbrElementIds[2 * srfcId + side];
406}
408template <MInt nDim, class SysEqn>
410// Prevent accidental compilation without support for SoA layout
411#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
412#error Missing implementation for structure-of-arrays memory layout.
413#endif
414 ENSURE_VALID_ID_ACCESSOR(srfcId);
415 ENSURE_VALID_SIDE_ACCESSOR(side);
416 return m_nghbrElementIds[2 * srfcId + side];
417}
418
419
421template <MInt nDim, class SysEqn>
423// Prevent accidental compilation without support for SoA layout
424#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
425#error Missing implementation for structure-of-arrays memory layout.
426#endif
427 ENSURE_VALID_ID_ACCESSOR(srfcId);
428 ENSURE_VALID_SIDE_ACCESSOR(side);
429 return m_variables[2 * noValuesVariables() * srfcId + side * noValuesVariables()];
430}
432template <MInt nDim, class SysEqn>
434// Prevent accidental compilation without support for SoA layout
435#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
436#error Missing implementation for structure-of-arrays memory layout.
437#endif
438 ENSURE_VALID_ID_ACCESSOR(srfcId);
439 ENSURE_VALID_SIDE_ACCESSOR(side);
440 return m_variables[2 * noValuesVariables() * srfcId + side * noValuesVariables()];
441}
442
443
445template <MInt nDim, class SysEqn>
447// Prevent accidental compilation without support for SoA layout
448#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
449#error Missing implementation for structure-of-arrays memory layout.
450#endif
451 ENSURE_VALID_ID_ACCESSOR(srfcId);
452 ENSURE_VALID_SIDE_ACCESSOR(side);
453 return m_nodeVars[2 * noValuesNodeVars() * srfcId + side * noValuesNodeVars()];
454}
456template <MInt nDim, class SysEqn>
458// Prevent accidental compilation without support for SoA layout
459#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
460#error Missing implementation for structure-of-arrays memory layout.
461#endif
462 ENSURE_VALID_ID_ACCESSOR(srfcId);
463 ENSURE_VALID_SIDE_ACCESSOR(side);
464 return m_nodeVars[2 * noValuesNodeVars() * srfcId + side * noValuesNodeVars()];
465}
466
467
469template <MInt nDim, class SysEqn>
471 resetStorage(1, m_orientation);
472 resetStorage(2, m_nghbrElementIds);
473 resetStorage(1, m_fineCellId);
474 resetStorage(1, m_internalSideId);
475 resetStorage(1, m_polyDeg);
476 resetStorage(1, m_noNodes1D);
477 resetStorage(1, m_globalId);
478 resetStorage(2 * noValuesVariables(), m_variables);
479 resetStorage(2 * noValuesNodeVars(), m_nodeVars);
480 resetStorage(nDim, m_coordinates);
481 resetStorage(noValuesNodeCoordinates(), m_nodeCoordinates);
482 resetStorage(noValuesFlux(), m_flux);
483}
484
485
487template <MInt nDim, class SysEqn>
489// Prevent accidental compilation without support for SoA layout
490#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
491#error Missing implementation for structure-of-arrays memory layout.
492#endif
493
494 fill_invalid(m_orientation, begin, end);
495
496 fill_invalid(m_nghbrElementIds, begin, end, 2);
497
498 fill_invalid(m_fineCellId, begin, end);
499
500 fill_invalid(m_internalSideId, begin, end);
501
502 fill_invalid(m_polyDeg, begin, end);
503
504 fill_invalid(m_noNodes1D, begin, end);
505
506 fill_invalid(m_globalId, begin, end);
507
508 fill_invalid(m_variables, begin, end, 2 * noValuesVariables());
509
510 fill_invalid(m_nodeVars, begin, end, 2 * noValuesNodeVars());
511
512 fill_invalid(m_coordinates, begin, end, nDim);
513
514 fill_invalid(m_nodeCoordinates, begin, end, noValuesNodeCoordinates());
515
516 fill_invalid(m_flux, begin, end, noValuesFlux());
517}
518
519
521template <MInt nDim, class SysEqn>
522template <class Functor, class T>
523void SurfaceCollector<nDim, SysEqn>::rawCopyGeneric(Functor&& c, const T& source, const MInt begin, const MInt end,
524 const MInt destination) {
525// Prevent accidental compilation without support for SoA layout
526#ifdef DGCOLLECTOR_SOA_MEMORY_LAYOUT
527#error Missing implementation for structure-of-arrays memory layout.
528#endif
529
530 copyData(source.m_orientation, m_orientation, c, begin, end, destination);
531
532 copyData(source.m_nghbrElementIds, m_nghbrElementIds, c, begin, end, destination, 2);
533
534 copyData(source.m_fineCellId, m_fineCellId, c, begin, end, destination);
535
536 copyData(source.m_internalSideId, m_internalSideId, c, begin, end, destination);
537
538 copyData(source.m_polyDeg, m_polyDeg, c, begin, end, destination);
539
540 copyData(source.m_noNodes1D, m_noNodes1D, c, begin, end, destination);
541
542 copyData(source.m_globalId, m_globalId, c, begin, end, destination);
543
544 copyData(source.m_variables, m_variables, c, begin, end, destination, 2 * noValuesVariables());
545
546 copyData(source.m_nodeVars, m_nodeVars, c, begin, end, destination, 2 * noValuesNodeVars());
547
548 copyData(source.m_coordinates, m_coordinates, c, begin, end, destination, nDim);
549
550 copyData(source.m_nodeCoordinates, m_nodeCoordinates, c, begin, end, destination, noValuesNodeCoordinates());
551
552 copyData(source.m_flux, m_flux, c, begin, end, destination, noValuesFlux());
553}
554
555} // namespace collector
556} // namespace dg
557} // namespace maia
558
559
560// Undefine macros that should not be used outside this file
561#undef DGCOLLECTOR_SANITY_CHECKS_ACCESSORS
562#undef ENSURE_VALID_ID_ACCESSOR
563#undef ENSURE_VALID_SIDE_ACCESSOR
564#undef ENSURE_VALID_DIR_ACCESSOR
565
566#endif // MAIA_DGSURFACECOLLECTOR_H
void copyData(const Container_ &source, Container_ &target, Functor &&f, const MInt begin, const MInt end, const MInt dest, const MInt solverSize=1)
Copy [begin, end) range with given solver size from source to dest position of target.
Definition: container.h:138
void fill_invalid(Container_ &c, const MInt begin, const MInt end, const MInt solverSize=1, const T value=Invalid< T >::value())
Definition: container.h:131
void resetStorage(const MInt n, Storage< T > &c)
Create new container with given size and replace original one.
Definition: container.h:420
void reset(const MInt capacity)
Reset tree, re-create data structures with given capacity, and set size to zero.
Definition: container.h:187
Class that represents DG element collector.
Storage< MFloat > m_nodeCoordinates
Integration node coordinates.
MInt & internalSideId(const MInt srfcId)
Accessor for internal side id.
MInt maxNoNodes1D() const
Return maximum number of nodes 1D.
Storage< MFloat > m_nodeVars
Additional variables at each node.
Storage< MFloat > m_coordinates
Coordinates of the surface center.
typename maia::dg::collector::Invalid< T > Invalid
MInt maxPolyDeg() const
Return maximum polynomial degree.
Storage< MInt > m_fineCellId
H-refinement fine element id.
Storage< MInt > m_nghbrElementIds
Nghbr. element ids (or -1 of no neighbor)
MInt & noNodes1D(const MInt srfcId)
Accessor for number of nodes 1D.
Storage< MFloat > m_flux
Store the numerical (Riemann) flux.
Storage< MInt > m_noNodes1D
Number of nodes 1D of the neighbors.
constexpr SurfaceCollector()=default
Default c'tor does nothing.
Storage< MInt > m_internalSideId
Side id of the internal element.
MFloat & nodeVars(const MInt srfcId, const MInt side)
Accessor for node variables.
Storage< MInt > m_polyDeg
Polynomial degrees of the neighbors.
void rawCopyGeneric(Functor &&c, const T &source, const MInt begin, const MInt end, const MInt destination)
Helper function for rawCopy(). Destination may refer to beginning or end of target range.
MInt & nghbrElementIds(const MInt srfcId, const MInt side)
Accessor for neighbor element ids.
typename Base::template Storage< T > Storage
MInt maxNoNodesXD() const
Return maximum number if nodes XD.
MFloat & flux(const MInt srfcId)
Accessor for flux.
constexpr MInt noNodeVars() const
Return number of node variables.
MLong & globalId(const MInt srfcId)
Accessor for global id.
MInt & fineCellId(const MInt srfcId)
Accessor for fine cell id.
MInt noNodesXD(const MInt srfcId) const
Accessor for number of nodes XD (const version).
void invalidate(const MInt begin, const MInt end)
Erase range of nodes such that they contain no sensible values anymore.
MFloat & nodeCoords(const MInt srfcId)
Accessor for node coordinates.
MInt & polyDeg(const MInt srfcId)
Accessor for polynomial degree.
Storage< MInt > m_orientation
Orientiation of face normal vector.
void reset()
Reset SurfaceCollector, re-create data structures.
MFloat & variables(const MInt srfcId, const MInt side)
Accessor for variables.
MInt & orientation(const MInt srfcId)
Accessor for orientation.
Storage< MFloat > m_variables
Surface variables.
MFloat & coords(const MInt srfcId, const MInt dir)
Accessor for coordinates.
MInt ipow(MInt base, MInt exp)
Integer exponent function for non-negative exponents.
Definition: functions.h:317
int32_t MInt
Definition: maiatypes.h:62
double MFloat
Definition: maiatypes.h:52
int64_t MLong
Definition: maiatypes.h:64
Namespace for auxiliary functions/classes.