MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
acasurfacedatacollector.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 ACASURFACEDATACOLLECTOR_H_
8#define ACASURFACEDATACOLLECTOR_H_
9
10#include <algorithm>
11#include <numeric>
12#include <type_traits>
13#include <vector>
14#include "INCLUDE/maiamacro.h"
15#include "INCLUDE/maiatypes.h"
16#include "MEMORY/container.h"
17#include "UTIL/functions.h"
18#include "compiler_config.h"
19
20// The following macro enables the "Structure-of-Arrays" memory layout for multi-dimensional node
21// variables. This might be beneficial for GPU computations. Default is "Array-of-Structures".
22// Examples (for nodes nN with four children cM each)
23// Array-of-Structures (AOS): n0c0, n0c1, n0c2, n0c3, n1c0, n1c1, n1c2, n1c3, n2c0, n2c1, ...
24// Structure-of-Arrays (SOA): n0c0, n1c0, n2c0, n3c0, ..., n0c1, n1c1, n2c1, n3c1, ..., n0c2, ...
25// #define ACACOLLECTOR_SOA_MEMORY_LAYOUT
26
27// The macro 'ACACOLLECTOR_SANITY_CHECKS_ACCESSORS' enables (potentially very expensive) sanity
28// checks
29// for all accessors. It is enabled for build type "extra_debug".
30//#ifdef MAIA_EXTRA_DEBUG
31// NOTE: enable checks in normal debug mode until everything is working correctly!
32#ifndef NDEBUG
33#define ACACOLLECTOR_SANITY_CHECKS_ACCESSORS
34#endif
35
36// Sanity-checking macros for accessors
37#if defined(ACACOLLECTOR_SANITY_CHECKS_ACCESSORS) || defined(MAIA_ASSERT_ACCESSORS)
38#define ENSURE_VALID_ID_ACCESSOR(id) \
39 do { \
40 MAIA_CONTAINER_ENSURE_VALID_ID(id); \
41 } while(false)
42#define ENSURE_VALID_VARIABLE_ID_ACCESSOR(id) \
43 do { \
44 MAIA_CONTAINER_ENSURE( \
45 id >= 0 && id < noVars(), \
46 "variable id " + std::to_string(id) + " out-of-bounds [0, " + std::to_string(noVars()) + ")", AT_); \
47 } while(false)
48#define ENSURE_VALID_SAMPLE_ID_ACCESSOR(id) \
49 do { \
50 MAIA_CONTAINER_ENSURE( \
51 id >= 0 && id < noSamples(), \
52 "sample id " + std::to_string(id) + " out-of-bounds [0, " + std::to_string(noSamples()) + ")", AT_); \
53 } while(false)
54#define ENSURE_VALID_DIR_ID_ACCESSOR(id) \
55 do { \
56 MAIA_CONTAINER_ENSURE(id >= 0 && id < nDim, \
57 "direction id = " + std::to_string(id) + " out-of-bounds [0, " + std::to_string(nDim) + ")", \
58 AT_); \
59 } while(false)
60#define ENSURE_CONDITION(condition, message) \
61 do { \
62 MAIA_CONTAINER_ENSURE(condition, message, AT_); \
63 } while(false)
64#else
65#define ENSURE_VALID_ID_ACCESSOR(id) \
66 do { \
67 } while(false)
68#define ENSURE_VALID_VARIABLE_ID_ACCESSOR(id) \
69 do { \
70 } while(false)
71#define ENSURE_VALID_SAMPLE_ID_ACCESSOR(id) \
72 do { \
73 } while(false)
74#define ENSURE_VALID_DIR_ID_ACCESSOR(id) \
75 do { \
76 } while(false)
77#define ENSURE_CONDITION(condition, message) \
78 do { \
79 } while(false)
80#endif
81
82
84namespace maia {
85namespace acoustic_analogy {
86namespace collector {
87
88// Type traits for invalid values. These values are used to initialize/erase nodes
89template <class T>
90struct Invalid {};
91
92// Invalid value for ids is 'INT_MIN'
93template <>
94struct Invalid<MInt> {
95 static constexpr MInt value() { return std::numeric_limits<MInt>::min(); }
96};
97
98// Invalid value for longs is 'INT_MIN'
99template <>
100struct Invalid<MLong> {
101 static constexpr MLong value() { return std::numeric_limits<MLong>::min(); }
102};
103
104// Invalid value for floats is 'NaN'
105template <>
107 static constexpr MFloat value() {
108#ifdef MAIA_PGI_COMPILER
109 return std::numeric_limits<MFloat>::quiet_NaN();
110#else
111 return std::numeric_limits<MFloat>::signaling_NaN();
112#endif
113 }
114};
115
116
118template <MInt nDim>
119class SurfaceDataCollector : public maia::container::Container<SurfaceDataCollector<nDim>, Invalid> {
120 // Necessary for CRTP
122
123 // Make base class functions known to use without this pointer
125 using Base::resetStorage;
127 template <class T>
128 using Storage = typename Base::template Storage<T>;
129
130 public:
131 // Types
132 template <class T>
134
135 // Constructor
137 constexpr SurfaceDataCollector() = default;
138
139 // Ensure that base class method is found when called from outside
140 using Base::copyData;
141 using Base::fill_invalid;
142 using Base::reset;
143 using Base::resize;
144
145 // Accessors
146 MFloat& surfaceCoordinates(const MInt id);
147 MFloat surfaceCoordinates(const MInt id) const;
148
149 MFloat& surfaceArea(const MInt id);
150 MFloat surfaceArea(const MInt id) const;
151
152 MFloat& surfaceNormal(const MInt id);
153 MFloat surfaceNormal(const MInt id) const;
154
155 MFloat& variables(const MInt id, const MInt var);
156 MFloat& variables(const MInt id) { return variables(id, 0); };
157
158 MFloat& variables(const MInt id, const MInt var, const MInt sample);
159 MFloat variables(const MInt id, const MInt var, const MInt sample) const;
160
161 MFloat& complexVariables(const MInt id, const MInt var);
162 MFloat& complexVariables(const MInt id) { return complexVariables(id, 0); };
163
164 MFloat& complexVariables(const MInt id, const MInt var, const MInt sample, const MInt component);
165 MFloat complexVariables(const MInt id, const MInt var, const MInt sample, const MInt component) const;
166
167 // Auxiliary methods
168
170 MInt noVars() { return m_noVars; }
172 void setNoVars(const MInt noVars_) {
173 ENSURE_CONDITION(noVars_ > 0 && noVars_ <= s_maxNoVars, "Invalid number of variables.");
174 m_noVars = noVars_;
175 };
176
180 void setNoComplexVars(const MInt noComplexVars_) {
181 ENSURE_CONDITION(noComplexVars_ > 0 && noComplexVars_ <= s_maxNoComplexVars,
182 "Invalid number of complex variables.");
183 m_noComplexVars = noComplexVars_;
184 };
185
189 void setNoSamples(const MInt noSamples_) {
190 ENSURE_CONDITION(noSamples_ > 0 && noSamples_ <= s_maxNoSamples, "Invalid number of samples.");
191 m_noSamples = noSamples_;
192 };
193
194 private:
195 // Methods required by base class for CRTP
196 void reset();
197 void resize() override;
198 void invalidate(const MInt begin, const MInt end);
199 template <class Functor, class T>
200 void rawCopyGeneric(Functor&& c, const T& source, const MInt begin, const MInt end, const MInt destination);
201
202 private:
203 // Member variables
204
205 // Number of variables
207
208 // Number of complex variables
210
211 // Number of samples
213
214 // Data containers
220
222 static constexpr MInt s_maxNoVars = 14;
224 static constexpr MInt s_maxNoComplexVars = 5;
226 static constexpr MInt s_maxNoSamples = 1048576; // 2^20
227};
228
229
231template <MInt nDim>
233 const MInt varSize = noVars() * noSamples();
234 const MInt complexVarSize = 2 * noComplexVars() * noSamples();
235
236 resetStorage(nDim, m_surfaceCoordinates);
237 resetStorage(1, m_surfaceArea);
238 resetStorage(nDim, m_surfaceNormal);
239 resetStorage(varSize, m_variables);
240 resetStorage(complexVarSize, m_complexVariables);
241}
242
244template <MInt nDim>
246 const MInt varSize = noVars() * noSamples();
247 const MInt complexVarSize = 2 * noComplexVars() * noSamples();
248
249 resizeStorage(nDim, m_surfaceCoordinates);
250 resizeStorage(1, m_surfaceArea);
251 resizeStorage(nDim, m_surfaceNormal);
252 resizeStorage(varSize, m_variables);
253 resizeStorage(complexVarSize, m_complexVariables);
254}
255
256
258template <MInt nDim>
260// Prevent accidental compilation without support for SoA layout
261#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
262#error Missing implementation for structure-of-arrays memory layout.
263#endif
264 ENSURE_VALID_ID_ACCESSOR(id);
265 return m_surfaceCoordinates[id * nDim];
266}
268template <MInt nDim>
270// Prevent accidental compilation without support for SoA layout
271#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
272#error Missing implementation for structure-of-arrays memory layout.
273#endif
274 ENSURE_VALID_ID_ACCESSOR(id);
275 return m_surfaceCoordinates[id * nDim];
276}
277
278
280template <MInt nDim>
282// Prevent accidental compilation without support for SoA layout
283#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
284#error Missing implementation for structure-of-arrays memory layout.
285#endif
286 ENSURE_VALID_ID_ACCESSOR(id);
287 return m_surfaceArea[id];
288}
290template <MInt nDim>
292// Prevent accidental compilation without support for SoA layout
293#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
294#error Missing implementation for structure-of-arrays memory layout.
295#endif
296 ENSURE_VALID_ID_ACCESSOR(id);
297 return m_surfaceCoordinates[id];
298}
299
300
302template <MInt nDim>
304// Prevent accidental compilation without support for SoA layout
305#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
306#error Missing implementation for structure-of-arrays memory layout.
307#endif
308 ENSURE_VALID_ID_ACCESSOR(id);
309 return m_surfaceNormal[id * nDim];
310}
312template <MInt nDim>
314// Prevent accidental compilation without support for SoA layout
315#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
316#error Missing implementation for structure-of-arrays memory layout.
317#endif
318 ENSURE_VALID_ID_ACCESSOR(id);
319 return m_surfaceNormal[id * nDim];
320}
321
322
324template <MInt nDim>
326// Prevent accidental compilation without support for SoA layout
327#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
328#error Missing implementation for structure-of-arrays memory layout.
329#endif
330 ENSURE_VALID_ID_ACCESSOR(id);
331 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
332 return m_variables[id * noVars() * noSamples() + var * noSamples()];
333}
334
335
339template <MInt nDim>
340MFloat& SurfaceDataCollector<nDim>::variables(const MInt id, const MInt var, const MInt sample) {
341// Prevent accidental compilation without support for SoA layout
342#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
343#error Missing implementation for structure-of-arrays memory layout.
344#endif
345 ENSURE_VALID_ID_ACCESSOR(id);
346 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
347 ENSURE_VALID_SAMPLE_ID_ACCESSOR(sample);
348 return m_variables[id * noVars() * noSamples() + var * noSamples() + sample];
349}
351template <MInt nDim>
352MFloat SurfaceDataCollector<nDim>::variables(const MInt id, const MInt var, const MInt sample) const {
353// Prevent accidental compilation without support for SoA layout
354#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
355#error Missing implementation for structure-of-arrays memory layout.
356#endif
357 ENSURE_VALID_ID_ACCESSOR(id);
358 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
359 ENSURE_VALID_SAMPLE_ID_ACCESSOR(sample);
360 return m_variables[id * noVars() * noSamples() + var * noSamples() + sample];
361}
362
363
365template <MInt nDim>
367// Prevent accidental compilation without support for SoA layout
368#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
369#error Missing implementation for structure-of-arrays memory layout.
370#endif
371 ENSURE_VALID_ID_ACCESSOR(id);
372 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
373 return m_complexVariables[id * 2 * noComplexVars() * noSamples() + var * 2 * noSamples()];
374}
375
376
380template <MInt nDim>
382 const MInt component) {
383// Prevent accidental compilation without support for SoA layout
384#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
385#error Missing implementation for structure-of-arrays memory layout.
386#endif
387 ENSURE_VALID_ID_ACCESSOR(id);
388 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
389 ENSURE_VALID_SAMPLE_ID_ACCESSOR(sample);
390 return m_complexVariables[id * 2 * noComplexVars() * noSamples() + var * 2 * noSamples() + 2 * sample + component];
391}
393template <MInt nDim>
395 const MInt component) const {
396// Prevent accidental compilation without support for SoA layout
397#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
398#error Missing implementation for structure-of-arrays memory layout.
399#endif
400 ENSURE_VALID_ID_ACCESSOR(id);
401 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
402 ENSURE_VALID_SAMPLE_ID_ACCESSOR(sample);
403 return m_complexVariables[id * 2 * noComplexVars() * noSamples() + var * 2 * noSamples() + 2 * sample + component];
404}
405
406
408template <MInt nDim>
410// Prevent accidental compilation without support for SoA layout
411#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
412#error Missing implementation for structure-of-arrays memory layout.
413#endif
414
415 const MInt varSize = noVars() * noSamples();
416 const MInt complexVarSize = 2 * noComplexVars() * noSamples();
417
418 // Surface coordinates
419 fill_invalid(m_surfaceCoordinates, begin, end, nDim);
420
421 // Surface area
422 fill_invalid(m_surfaceArea, begin, end);
423
424 // Surface normal
425 fill_invalid(m_surfaceNormal, begin, end, nDim);
426
427 // Variables
428 fill_invalid(m_variables, begin, end, varSize);
429
430 // Complex variables
431 fill_invalid(m_complexVariables, begin, end, complexVarSize);
432}
433
434
436template <MInt nDim>
437template <class Functor, class T>
438void SurfaceDataCollector<nDim>::rawCopyGeneric(Functor&& c, const T& source, const MInt begin, const MInt end,
439 const MInt destination) {
440// Prevent accidental compilation without support for SoA layout
441#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
442#error Missing implementation for structure-of-arrays memory layout.
443#endif
444
445 const MInt varSize = noVars() * noSamples();
446 const MInt complexVarSize = 2 * noComplexVars() * noSamples();
447
448 // Surface coordinates
449 copyData(source.m_surfaceCoordinates, m_surfaceCoordinates, c, begin, end, destination, nDim);
450
451 // Surface area
452 copyData(source.m_surfaceArea, m_surfaceArea, c, begin, end, destination);
453
454 // Surface normal
455 copyData(source.m_surfaceNormal, m_surfaceNormal, c, begin, end, destination, nDim);
456
457 // Variables
458 copyData(source.m_variables, m_variables, c, begin, end, destination, varSize);
459
460 // Variables
461 copyData(source.m_complexVariables, m_complexVariables, c, begin, end, destination, complexVarSize);
462}
463
464
465} // namespace collector
466} // namespace acoustic_analogy
467} // namespace maia
468
469
470// Undefine macros that should not be used outside this file
471#undef ACACOLLECTOR_SANITY_CHECKS_ACCESSORS
472#undef ENSURE_VALID_ID_ACCESSOR
473#undef ENSURE_VALID_VARIABLE_ID_ACCESSOR
474#undef ENSURE_VALID_SAMPLE_ID_ACCESSOR
475#undef ENSURE_VALID_DIR_ID_ACCESSOR
476#undef ENSURE_CONDITION
477
478#endif // ifndef DGELEMENTCOLLECTOR_H_
MFloat & variables(const MInt id, const MInt var)
Accessor for variables.
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.
MFloat & surfaceArea(const MInt id)
Accessor for surface area (or segment length in 2D).
MFloat & complexVariables(const MInt id, const MInt var)
Accessor for complex variables.
MFloat & surfaceCoordinates(const MInt id)
Accessor for surface element coordinates.
void setNoVars(const MInt noVars_)
Set number of variables.
void reset()
Reset, re-create data structures with given capacity, and set size to zero.
MInt noSamples()
Return number of samples (i.e. number of time steps)
void invalidate(const MInt begin, const MInt end)
Erase range of nodes such that they contain no sensible values anymore.
void setNoComplexVars(const MInt noComplexVars_)
Set number of complex variables.
constexpr SurfaceDataCollector()=default
Default c'tor does nothing.
void resize() override
Resize data strucutres reusing values from previous state.
static constexpr MInt s_maxNoSamples
Maximum number of samples.
void setNoSamples(const MInt noSamples_)
Set number of samples.
MFloat & surfaceNormal(const MInt id)
Accessor for surface normal.
static constexpr MInt s_maxNoComplexVars
Maximum number of complex variables (in the frequency domain)
MInt noComplexVars()
Return number of complex variables.
static constexpr MInt s_maxNoVars
Maximum number of variables (in the time domain)
typename maia::acoustic_analogy::collector::Invalid< T > Invalid
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 resizeStorage(const MInt n, Storage< T > &c)
Resize container with given size.
Definition: container.h:436
void reset(const MInt capacity)
Reset tree, re-create data structures with given capacity, and set size to zero.
Definition: container.h:187
int32_t MInt
Definition: maiatypes.h:62
double MFloat
Definition: maiatypes.h:52
int64_t MLong
Definition: maiatypes.h:64
MInt id
Definition: maiatypes.h:71
Namespace for auxiliary functions/classes.