VirtualFluids 0.2.0
Parallel CFD LBM Solver
Loading...
Searching...
No Matches
FFTCalculator.cpp
Go to the documentation of this file.
1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
15//
16// This file is part of VirtualFluids. VirtualFluids is free software: you can
17// redistribute it and/or modify it under the terms of the GNU General Public
18// License as published by the Free Software Foundation, either version 3 of
19// the License, or (at your option) any later version.
20//
21// VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
22// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24// for more details.
25//
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
28//
32//=======================================================================================
33#include "FFTCalculator.h"
34
36
37#define _USE_MATH_DEFINES
38#include <fstream>
39#include <math.h>
40
41std::shared_ptr<FFTCalculator> FFTCalculator::getInstance()
42{
43 static std::shared_ptr<FFTCalculator> uniqueInstance;
44 if (!uniqueInstance)
45 uniqueInstance = std::shared_ptr<FFTCalculator>(new FFTCalculator());
46 return uniqueInstance;
47}
48
49double FFTCalculator::calcNy(std::vector<std::vector<double>> data, bool transposeData, int lx, int lz,
50 int timeStepLength)
51{
52 this->lx = (double)lx;
53 this->lz = (double)lz;
54 this->timeStepLength = (double)timeStepLength;
55 this->transposeData = transposeData;
56 if (!transposeData)
57 this->data = data;
58 else
59 this->data = transpose(data);
60
61 init();
62
63 double ny = calcNy();
64 return ny;
65}
66
67double FFTCalculator::calcPhiDiff(std::vector<std::vector<double>> data, bool transposeData, int lx, int lz,
68 int timeStepLength)
69{
70 this->lx = (double)lx;
71 this->lz = (double)lz;
72 this->timeStepLength = (double)timeStepLength;
73 this->transposeData = transposeData;
74 if (!transposeData)
75 this->data = data;
76 else
77 this->data = transpose(data);
78
79 init();
80
81 double phidiff = calcPhiDiff();
82
83 return abs(phidiff);
84}
85
86FFTCalculator::FFTCalculator()
87{
88}
89
90double FFTCalculator::calcAmplitudeForTimeStep(std::vector<double> data, bool transposeData, int lx, int lz)
91{
92 this->lx = (double)lx;
93 this->lz = (double)lz;
94 init();
95 this->transposeData = transposeData;
96 this->data.resize(0);
97 this->data.push_back(data);
98 std::vector<double> amplitude = calcAmplitudeForAllSteps();
99 return amplitude.at(0);
100}
101
102void FFTCalculator::init()
103{
104 fftResultsIm.clear();
105 fftResultsRe.clear();
106 fftCalculated = false;
107}
108
110{
111 std::vector<double> logAmplitude = calcLogAmplitudeForAllSteps();
112 std::vector<double> linReg = calcLinReg(logAmplitude);
113 double nu =
114 -(1.0 / (((2.0 * M_PI / lz) * (2.0 * M_PI / lz) + (2.0 * M_PI / lx) * (2.0 * M_PI / lx)) * timeStepLength)) *
115 linReg.at(0);
116 return nu;
117}
118
120{
121 std::vector<double> phi = calcPhiForAllSteps();
122 std::vector<double> linReg = calcLinReg(phi);
123
124 return linReg.at(0);
125}
126
127std::vector<double> FFTCalculator::calcLinReg(std::vector<double> y)
128{
129 std::vector<double> result;
130 std::vector<double> x(y.size());
131 double sumX = 0.0;
132 double sumY = 0.0;
133
134 for (int i = 0; i < y.size(); i++) {
135 sumY += y.at(i);
136 x.at(i) = i;
137 sumX += i;
138 }
139 double avgX = sumX / y.size();
140 double avgY = sumY / y.size();
141 double zaehler = 0.0;
142 double nenner = 0.0;
143 for (int i = 0; i < y.size(); i++) {
144 zaehler += (x.at(i) - avgX) * (y.at(i) - avgY);
145 nenner += (x.at(i) - avgX) * (x.at(i) - avgX);
146 }
147 double a1 = zaehler / nenner;
148 result.push_back(a1);
149 double a0 = avgY - a1 * avgX;
150 result.push_back(a0);
151
152 double ess = 0;
153 double tss = 0;
154 for (int i = 0; i < y.size(); i++) {
155 ess += ((a0 + a1 * x.at(i)) - avgY) * ((a0 + a1 * x.at(i)) - avgY);
156 tss += (y.at(i) - avgY) * (y.at(i) - avgY);
157 }
158 double r2 = ess / tss;
159 result.push_back(r2);
160 return result;
161}
162
163std::vector<double> FFTCalculator::calcLogAmplitudeForAllSteps()
164{
165 std::vector<double> amplitude = calcAmplitudeForAllSteps();
166 std::vector<double> logAmplitude;
167 for (int i = 0; i < amplitude.size(); i++)
168 logAmplitude.push_back(log(amplitude.at(i)));
169
170 return logAmplitude;
171}
172
173std::vector<double> FFTCalculator::calcAmplitudeForAllSteps()
174{
175 std::vector<double> amplitude;
176 if (fftCalculated == false) {
177 for (int step = 0; step < data.size(); step++)
178 calcFFT2D(step);
179 fftCalculated = true;
180 }
181 int pos;
182 if (!transposeData)
183 pos = 2 + (lx - 1);
184 else
185 pos = 2 + (lz - 1);
186
187 for (int step = 0; step < data.size(); step++)
188 amplitude.push_back(4.0 / (lx * lz) *
189 sqrt(fftResultsRe.at(step).at(pos) * fftResultsRe.at(step).at(pos) +
190 fftResultsIm.at(step).at(pos) * fftResultsIm.at(step).at(pos)));
191
192 return amplitude;
193}
194
195std::vector<double> FFTCalculator::calcPhiForAllSteps()
196{
197 std::vector<double> phi;
198 if (fftCalculated == false) {
199 for (int step = 0; step < data.size(); step++)
200 calcFFT2D(step);
201 fftCalculated = true;
202 }
203 int pos;
204 if (!transposeData)
205 pos = 2 + (lx - 1);
206 else
207 pos = 2 + (lz - 1);
208
209 for (int step = 0; step < data.size(); step++) {
210 phi.push_back(atan(fftResultsIm.at(step).at(pos) / fftResultsRe.at(step).at(pos)));
211 }
212
213 return phi;
214}
215
216void FFTCalculator::calcFFT2D(unsigned int timeStep)
217{
218 fftw_complex *in = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * lx * lz);
219 fftw_complex *out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * lx * lz);
220
221 initDataForFFT(in, timeStep);
222
223 fftw_plan p;
224 if (!transposeData)
226 else
229
230 setFFTResults(out, timeStep);
231
233 fftw_free(in);
234 fftw_free(out);
235}
236
237std::vector<std::vector<double>> FFTCalculator::transpose(std::vector<std::vector<double>> dataToTranspose)
238{
239 std::vector<std::vector<std::vector<double>>> dataInLx;
240 dataInLx.resize(dataToTranspose.size());
241 for (int i = 0; i < dataInLx.size(); i++) {
242 dataInLx.at(i).resize(lz);
243 for (int j = 0; j < dataInLx.at(i).size(); j++)
244 dataInLx.at(i).at(j).resize(lx);
245 }
246 for (int timeStep = 0; timeStep < dataInLx.size(); timeStep++) {
247 for (int posInLZ = 0; posInLZ < lz; posInLZ++)
248 for (int posInLX = 0; posInLX < lx; posInLX++)
249 dataInLx.at(timeStep).at(posInLZ).at(posInLX) = dataToTranspose.at(timeStep).at(posInLX + posInLZ * lx);
250 }
251
252 std::vector<std::vector<std::vector<double>>> dataInLz;
253 dataInLz.resize(dataToTranspose.size());
254 for (int i = 0; i < dataInLx.size(); i++) {
255 dataInLz.at(i).resize(lx);
256 for (int j = 0; j < dataInLz.at(i).size(); j++)
257 dataInLz.at(i).at(j).resize(lz);
258 }
259
260 for (int timeStep = 0; timeStep < dataInLz.size(); timeStep++) {
261 for (int posInLX = 0; posInLX < lx; posInLX++)
262 for (int posInLZ = 0; posInLZ < lz; posInLZ++)
263 dataInLz.at(timeStep).at(posInLX).at(posInLZ) = dataInLx.at(timeStep).at(posInLZ).at(posInLX);
264 }
265
266 std::vector<std::vector<double>> result;
267 result.resize(dataToTranspose.size());
268
269 for (int timeStep = 0; timeStep < dataInLz.size(); timeStep++) {
270 result.at(timeStep).resize(0);
271 for (int posInLX = 0; posInLX < lx; posInLX++)
272 for (int posInLZ = 0; posInLZ < lz; posInLZ++)
273 result.at(timeStep).push_back(dataInLz.at(timeStep).at(posInLX).at(posInLZ));
274 }
275 return result;
276}
277
278void FFTCalculator::initDataForFFT(fftw_complex *input, unsigned int step)
279{
280 for (int i = 0; i < data.at(step).size(); i++) {
281 input[i][0] = data.at(step).at(i);
282 input[i][1] = 0;
283 }
284}
285
286void FFTCalculator::setFFTResults(fftw_complex *result, unsigned int step)
287{
288 std::vector<double> fftRe, fftIm;
289 fftRe.resize(data.at(step).size());
290 fftIm.resize(data.at(step).size());
291
292 for (int i = 0; i < data.at(step).size(); i++) {
293 fftRe.at(i) = result[i][0];
294 fftIm.at(i) = result[i][1];
295 }
296 fftResultsIm.push_back(fftIm);
297 fftResultsRe.push_back(fftRe);
298}
double calcAmplitudeForTimeStep(std::vector< double > data, bool transposeData, int lx, int lz)
double calcNy(std::vector< std::vector< double > > data, bool transposeData, int lx, int lz, int timeStepLength)
void log(const char *fmt)
static std::shared_ptr< FFTCalculator > getInstance()
double calcPhiDiff(std::vector< std::vector< double > > data, bool transposeData, int lx, int lz, int timeStepLength)
std::shared_ptr< T > SPtr
@ x
Definition Axis.h:42
@ y
Definition Axis.h:43