MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
acapostprocessing.hpp
Go to the documentation of this file.
1#include "acapostprocessing.h"
2
3#include <vector>
4#include "INCLUDE/maiatypes.h"
5
9template <MInt nDim>
11 private:
14 const MFloat m_gamma = 1.4;
15 std::vector<MFloat> m_oaspl;
16
17 public:
19 void init_() override;
20 void calc(const MInt observerId, const MFloat* const data, const MFloat* const dataComplex = nullptr) override;
21 void finish() override;
22};
23
24template <MInt nDim>
26 m_fileNameIoParallel = m_outPath + "OASPL" + ParallelIo::fileExt();
27 m_oaspl.resize(m_noObservers, 0.0);
28
29 constexpr MFloat pRefDim = 2e-5; // [Pa]
30 MFloat pInftyDim = 101325; // [Pa] = (rho_infty * a_infty^2 ) / gamma
31 pInftyDim = Context::getBasicProperty<MFloat>("pInftyDimensional", AT_, &pInftyDim);
32 m_pRefSq = POW2(pRefDim / (m_gamma * pInftyDim)); // [-]
33}
34
35template <MInt nDim>
36void AcaPostProcessingOASPL<nDim>::calc(const MInt observerId, const MFloat* const data,
37 const MFloat* const /*dataComplex*/) {
38 // Calculation of overall sound pressure level using p_rms (could also be computed by the sum of
39 // spl over all frequencies)
40 MFloat p_rms = 0.0;
41 for(MInt t = 0; t < m_noSamples; t++) {
42 p_rms += POW2(data[t]);
43 }
44 p_rms = p_rms / m_noSamples;
45 // Calculate overall sound pressure level for this observer
46 m_oaspl[observerId] = 10.0 * log10(p_rms / m_pRefSq);
47}
48
49template <MInt nDim>
51 using namespace maia::parallel_io;
52 ParallelIo file(m_fileNameIoParallel, PIO_REPLACE, m_mpiComm);
53 ParallelIo::size_type dimSizesCoordinates[] = {m_noGlobalObservers, nDim};
54 file.defineArray(PIO_FLOAT, "coordinates", 2, &dimSizesCoordinates[0]);
55 file.defineArray(PIO_FLOAT, "OASPL", m_noGlobalObservers);
56
57 const MBool isRoot = (m_rank == 0);
58 file.setOffset((isRoot) ? m_noGlobalObservers : 0, 0, 2);
59 file.writeArray(m_coords, "coordinates");
60 file.setOffset(m_noObservers, m_offsetObserver);
61 file.writeArray(m_oaspl.data(), "OASPL");
62}
63
67template <MInt nDim>
69 private:
71 std::vector<MFloat> m_pabs;
72
73 public:
75 void init_() override;
76 void calc(const MInt observerId, const MFloat* const data, const MFloat* const dataComplex = nullptr) override;
77 void finish() override;
78};
79
80template <MInt nDim>
82 m_fileNameIoParallel = m_outPath + "pressABS" + ParallelIo::fileExt();
83 m_pabs.resize(m_noObservers * m_noSamples, 0.0);
84}
85
86template <MInt nDim>
87void AcaPostProcessingPABS<nDim>::calc(const MInt observerId, const MFloat* const /*data*/,
88 const MFloat* const dataComplex) {
89 const MInt offset = observerId * m_noSamples;
90 for(MInt t = 1; t < m_noSamples; t++) { // Skip frequency 0
91 const MFloat real = dataComplex[t * 2 + 0];
92 const MFloat imag = dataComplex[t * 2 + 1];
93 // product of p * p_complex_conjugate = p_re_sq + p_im_sq = [abs(p)]^2
94 const MFloat p_magnSq = POW2(real) + POW2(imag);
95 // Absolute pressure
96 m_pabs[offset + t] = 2 * sqrt(p_magnSq);
97 }
98}
99
100template <MInt nDim>
102 using namespace maia::parallel_io;
103 ParallelIo file(m_fileNameIoParallel, PIO_REPLACE, m_mpiComm);
104 ParallelIo::size_type dimSizesCoordinates[] = {m_noGlobalObservers, nDim};
105 ParallelIo::size_type dimSizes[] = {m_noGlobalObservers, m_noSamples};
106 file.defineArray(PIO_FLOAT, "coordinates", 2, &dimSizesCoordinates[0]);
107 file.defineArray(PIO_FLOAT, "pressABS", 2, &dimSizes[0]);
108
109 const MBool isRoot = (m_rank == 0);
110 file.setOffset((isRoot) ? m_noGlobalObservers : 0, 0, 2);
111 file.writeArray(m_coords, "coordinates");
112 ScratchSpace<MFloat> pressABS(m_noObservers, m_noSamples, AT_, "pressABS");
113 file.setOffset(m_noObservers, m_offsetObserver, 2);
114 for(MInt obs = 0; obs < m_noObservers; obs++) {
115 const MInt offset = obs * m_noSamples;
116 for(MInt t = 0; t < m_noSamples; t++) {
117 pressABS(obs, t) = m_pabs[offset + t];
118 }
119 }
120 file.writeArray(pressABS.data(), "pressABS");
121}
122
126template <MInt nDim>
128 private:
131 std::vector<MFloat> m_prms;
132
133 public:
135 void init_() override;
136 void calc(const MInt observerId, const MFloat* const data, const MFloat* const dataComplex = nullptr) override;
137 void finish() override;
138};
139
140template <MInt nDim>
142 m_fileNameIoParallel = m_outPath + "RMSpressure" + ParallelIo::fileExt();
143 m_fileNameIoDat = m_outPath + "RMS.dat";
144 m_prms.resize(m_noGlobalObservers, 0.0);
145}
146
147template <MInt nDim>
148void AcaPostProcessingRMS<nDim>::calc(const MInt observerId, const MFloat* const data,
149 const MFloat* const /*dataComplex*/) {
150 // Calculation of root mean square pressure values
151 m_prms[m_offsetObserver + observerId] = 0;
152 for(MInt t = 0; t < m_noSamples; t++) {
153 m_prms[m_offsetObserver + observerId] += POW2(data[t]);
154 }
155 m_prms[m_offsetObserver + observerId] = sqrt(m_prms[m_offsetObserver + observerId] / m_noSamples);
156}
157
158template <MInt nDim>
160 constexpr MInt rootId = 0;
161 using namespace maia::parallel_io;
162 ParallelIo file(m_fileNameIoParallel, PIO_REPLACE, m_mpiComm);
163 ParallelIo::size_type dimSizesCoordinates[] = {m_noGlobalObservers, nDim};
164 file.defineArray(PIO_FLOAT, "coordinates", 2, &dimSizesCoordinates[0]);
165 file.defineArray(PIO_FLOAT, "rms_pressure", m_noGlobalObservers);
166
167 const MBool isRoot = (m_rank == rootId);
168 file.setOffset((isRoot) ? m_noGlobalObservers : 0, 0, 2);
169 file.writeArray(m_coords, "coordinates");
170 if(isRoot) {
171 MPI_Reduce(MPI_IN_PLACE, m_prms.data(), m_noGlobalObservers, maia::type_traits<MFloat>::mpiType(), MPI_SUM, rootId,
172 m_mpiComm, AT_, "MPI_IN_PLACE", "m_prms");
173 // TODO labels:ACA,totest Check distl, theta, and alpha
174 std::ofstream outfile;
175 outfile.open(m_fileNameIoDat);
176 if constexpr(nDim == 2) {
177 outfile << "# obs:1 x:2 y:3 theta:4 p_rms:5" << std::endl;
178 for(MInt obs = 0; obs < m_noGlobalObservers; obs++) {
179 const MFloat* const obsCoord = &m_coords[nDim * obs];
180 const MFloat theta = atan2(obsCoord[1], obsCoord[0]);
181 outfile << obs << " " << obsCoord[0] << " " << obsCoord[1] << " " << theta << " " << m_prms[obs] << std::endl;
182 }
183 } else if constexpr(nDim == 3) {
184 outfile << "# obs:1 x:2 y:3 z:4 theta:5 alpha:6 p_rms:7" << std::endl;
185 for(MInt obs = 0; obs < m_noGlobalObservers; obs++) {
186 const MFloat* const obsCoord = &m_coords[nDim * obs];
187 const MFloat dist = sqrt(POW2(obsCoord[0]) + POW2(obsCoord[1]) + POW2(obsCoord[2]));
188 const MFloat theta = atan2(obsCoord[2], obsCoord[0]);
189 const MFloat alpha = asin(obsCoord[1] / dist);
190 outfile << obs << " " << obsCoord[0] << " " << obsCoord[1] << " " << obsCoord[2] << " " << theta << " " << alpha
191 << " " << m_prms[obs] << std::endl;
192 }
193 }
194 outfile.close();
195 file.setOffset(m_noGlobalObservers, 0);
196 } else {
197 MPI_Reduce(m_prms.data(), nullptr, m_noGlobalObservers, maia::type_traits<MFloat>::mpiType(), MPI_SUM, rootId,
198 m_mpiComm, AT_, "MPI_IN_PLACE", "m_prms");
199 file.setOffset(0, 0);
200 }
201 file.writeArray(m_prms.data(), "rms_pressure");
202}
203
207template <MInt nDim>
209 private:
212 const MFloat m_gamma = 1.4;
213 std::vector<MFloat> m_spl;
214
215 public:
217 void init_() override;
218 void calc(const MInt observerId, const MFloat* const data, const MFloat* const dataComplex = nullptr) override;
219 void finish() override;
220};
221
222template <MInt nDim>
224 m_fileNameIoParallel = m_outPath + "SPL" + ParallelIo::fileExt();
225 // reference pressure: Attention: The default value needs to be made non-dimensional
237 constexpr MFloat pRefDim = 2e-5; // [Pa]
238 MFloat pInftyDim = 101325; // [Pa] = (rho_infty * a_infty^2 ) / gamma
239 pInftyDim = Context::getBasicProperty<MFloat>("pInftyDimensional", AT_, &pInftyDim);
240 m_pRefSq = POW2(pRefDim / (m_gamma * pInftyDim)); // [-]
241
242 m_spl.resize(m_noObservers * m_noSamples, 0.0);
243}
244
245template <MInt nDim>
246void AcaPostProcessingSPL<nDim>::calc(const MInt observerId, const MFloat* const /*data*/,
247 const MFloat* const dataComplex) {
248 // Calculation of sound pressure level (pressure at each frequency)
249 const MInt offset = observerId * m_noSamples;
250 for(MInt t = 1; t < m_noSamples; t++) { // Skip frequency 0
251 const MFloat real = dataComplex[t * 2 + 0];
252 const MFloat imag = dataComplex[t * 2 + 1];
253 // p times p complex conjugate = p_re_sq + p_imag_sq
254 const MFloat pSq = POW2(real) + POW2(imag);
255 // Sound pressure for each observer point for each frequency
256 // Ref.: Mendez et al. (2013): https://doi.org/10.1260%2F1475-472X.12.1-2.1
257 // or Beranek and Ver (1992); Delfs, Basics of Aeroacoustics (2016); ...
258 // Remind: 20 * log(a) = 10 * log(a^2), and pSq is only halved value because of FFT
259 m_spl[offset + t] = 10 * log10(2 * pSq / m_pRefSq);
260 }
261}
262
263template <MInt nDim>
265 using namespace maia::parallel_io;
266 ParallelIo file(m_fileNameIoParallel, PIO_REPLACE, m_mpiComm);
267 ParallelIo::size_type dimSizesCoordinates[] = {m_noGlobalObservers, nDim};
268 ParallelIo::size_type dimSizesSpl[] = {m_noGlobalObservers, m_noSamples};
269 file.defineArray(PIO_FLOAT, "coordinates", 2, &dimSizesCoordinates[0]);
270 file.defineArray(PIO_FLOAT, "frequency", m_noSamples);
271 file.defineArray(PIO_FLOAT, "SPL", 2, &dimSizesSpl[0]);
272
273 const MBool isRoot = (m_rank == 0);
274 file.setOffset((isRoot) ? m_noGlobalObservers : 0, 0, 2);
275 file.writeArray(m_coords, "coordinates");
276 file.setOffset((isRoot) ? m_noSamples : 0, 0);
277 file.writeArray(m_frequencies, "frequency");
278 file.setOffset(m_noObservers, m_offsetObserver, 2);
279 file.writeArray(m_spl.data(), "SPL");
280}
Abstract class for ACA post processing.
AcaPostProcessing(const MPI_Comm comm)
ACA post processing class for overall sound pressure calculation.
MFloat m_pRefSq
void finish() override
std::vector< MFloat > m_oaspl
isentropic exponent
const MFloat m_gamma
void init_() override
MString m_fileNameIoParallel
void calc(const MInt observerId, const MFloat *const data, const MFloat *const dataComplex=nullptr) override
ACA post processing class for absoulte pressure calculation.
std::vector< MFloat > m_pabs
void init_() override
void calc(const MInt observerId, const MFloat *const data, const MFloat *const dataComplex=nullptr) override
void finish() override
MString m_fileNameIoParallel
ACA post processing class for calculation of root mean square pressure.
MString m_fileNameIoDat
void calc(const MInt observerId, const MFloat *const data, const MFloat *const dataComplex=nullptr) override
void finish() override
void init_() override
MString m_fileNameIoParallel
std::vector< MFloat > m_prms
ACA post processing class for sound pressure level calculation.
MFloat m_pRefSq
void init_() override
void finish() override
MString m_fileNameIoParallel
std::vector< MFloat > m_spl
isentropic exponent
const MFloat m_gamma
void calc(const MInt observerId, const MFloat *const data, const MFloat *const dataComplex=nullptr) override
This class is a ScratchSpace.
Definition: scratch.h:758
pointer data()
Definition: scratch.h:289
constexpr Real POW2(const Real x)
Definition: functions.h:119
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Reduce
PARALLELIO_DEFAULT_BACKEND ParallelIo
Definition: parallelio.h:292
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)
Definition: pointbox.h:54