mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: Refactored and improved noiseFFT library
This commit is contained in:
@ -1,25 +1,31 @@
|
|||||||
Kmesh = Kmesh
|
Kmesh = Kmesh
|
||||||
|
|
||||||
fft = fft
|
|
||||||
|
|
||||||
processes = processes
|
|
||||||
UOprocess = $(processes)/UOprocess
|
|
||||||
|
|
||||||
turbulence = turbulence
|
|
||||||
|
|
||||||
noise = noise
|
|
||||||
|
|
||||||
$(Kmesh)/Kmesh.C
|
$(Kmesh)/Kmesh.C
|
||||||
|
|
||||||
|
fft = fft
|
||||||
$(fft)/fft.C
|
$(fft)/fft.C
|
||||||
$(fft)/fftRenumber.C
|
$(fft)/fftRenumber.C
|
||||||
$(fft)/calcEk.C
|
$(fft)/calcEk.C
|
||||||
$(fft)/kShellIntegration.C
|
$(fft)/kShellIntegration.C
|
||||||
|
|
||||||
|
processes = processes
|
||||||
|
UOprocess = $(processes)/UOprocess
|
||||||
$(UOprocess)/UOprocess.C
|
$(UOprocess)/UOprocess.C
|
||||||
|
|
||||||
|
turbulence = turbulence
|
||||||
$(turbulence)/turbGen.C
|
$(turbulence)/turbGen.C
|
||||||
|
|
||||||
$(noise)/noiseFFT.C
|
noise = noise
|
||||||
|
$(noise)/noiseFFT/noiseFFT.C
|
||||||
|
$(noise)/noiseModels/noiseModel/noiseModel.C
|
||||||
|
$(noise)/noiseModels/noiseModel/noiseModelNew.C
|
||||||
|
$(noise)/noiseModels/pointNoise/pointNoise.C
|
||||||
|
$(noise)/noiseModels/surfaceNoise/surfaceNoise.C
|
||||||
|
|
||||||
|
|
||||||
|
windowModels = windowModels
|
||||||
|
$(windowModels)/windowModel/windowModel.C
|
||||||
|
$(windowModels)/windowModel/windowModelNew.C
|
||||||
|
$(windowModels)/Hanning/Hanning.C
|
||||||
|
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/librandomProcesses
|
LIB = $(FOAM_LIBBIN)/librandomProcesses
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/sampling/lnInclude \
|
||||||
|
-I$(LIB_SRC)/surfMesh/lnInclude
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-lfiniteVolume
|
-lfiniteVolume \
|
||||||
|
-lsampling \
|
||||||
|
-lsurfMesh
|
||||||
|
|||||||
@ -1,454 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "noiseFFT.H"
|
|
||||||
#include "IFstream.H"
|
|
||||||
#include "DynamicList.H"
|
|
||||||
#include "fft.H"
|
|
||||||
#include "SubField.H"
|
|
||||||
#include "mathematicalConstants.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::scalar Foam::noiseFFT::p0 = 2e-5;
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::noiseFFT::noiseFFT
|
|
||||||
(
|
|
||||||
const scalar deltat,
|
|
||||||
const scalarField& pressure
|
|
||||||
)
|
|
||||||
:
|
|
||||||
scalarField(pressure),
|
|
||||||
deltat_(deltat)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::noiseFFT::noiseFFT(const fileName& pFileName, const label skip)
|
|
||||||
:
|
|
||||||
scalarField(),
|
|
||||||
deltat_(0.0)
|
|
||||||
{
|
|
||||||
// Construct pressure data file
|
|
||||||
IFstream pFile(pFileName);
|
|
||||||
|
|
||||||
// Check pFile stream is OK
|
|
||||||
if (!pFile.good())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Cannot read file " << pFileName
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skip)
|
|
||||||
{
|
|
||||||
scalar dummyt, dummyp;
|
|
||||||
|
|
||||||
for (label i=0; i<skip; i++)
|
|
||||||
{
|
|
||||||
pFile >> dummyt;
|
|
||||||
|
|
||||||
if (!pFile.good() || pFile.eof())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Number of points in file " << pFileName
|
|
||||||
<< " is less than the number to be skipped = " << skip
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
pFile >> dummyp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar t = 0, T = 0;
|
|
||||||
DynamicList<scalar> pData(100000);
|
|
||||||
label i = 0;
|
|
||||||
|
|
||||||
while (!(pFile >> t).eof())
|
|
||||||
{
|
|
||||||
T = t;
|
|
||||||
pFile >> pData(i++);
|
|
||||||
}
|
|
||||||
|
|
||||||
deltat_ = T/pData.size();
|
|
||||||
|
|
||||||
this->transfer(pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::graph Foam::noiseFFT::pt() const
|
|
||||||
{
|
|
||||||
scalarField t(size());
|
|
||||||
forAll(t, i)
|
|
||||||
{
|
|
||||||
t[i] = i*deltat_;
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph
|
|
||||||
(
|
|
||||||
"p(t)",
|
|
||||||
"t [s]",
|
|
||||||
"p(t) [Pa]",
|
|
||||||
t,
|
|
||||||
*this
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::scalarField> Foam::noiseFFT::window
|
|
||||||
(
|
|
||||||
const label N,
|
|
||||||
const label ni
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
label windowOffset = N;
|
|
||||||
|
|
||||||
if ((N + ni*windowOffset) > size())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Requested window is outside set of data" << endl
|
|
||||||
<< "number of data = " << size() << endl
|
|
||||||
<< "size of window = " << N << endl
|
|
||||||
<< "window = " << ni
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp<scalarField> tpw(new scalarField(N));
|
|
||||||
scalarField& pw = tpw();
|
|
||||||
|
|
||||||
label offset = ni*windowOffset;
|
|
||||||
|
|
||||||
forAll(pw, i)
|
|
||||||
{
|
|
||||||
pw[i] = operator[](i + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tpw;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::scalarField> Foam::noiseFFT::Hanning(const label N) const
|
|
||||||
{
|
|
||||||
scalarField t(N);
|
|
||||||
forAll(t, i)
|
|
||||||
{
|
|
||||||
t[i] = i*deltat_;
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar T = N*deltat_;
|
|
||||||
|
|
||||||
return 2*(0.5 - 0.5*cos(constant::mathematical::twoPi*t/T));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::scalarField> Foam::noiseFFT::Pf
|
|
||||||
(
|
|
||||||
const tmp<scalarField>& tpn
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
tmp<scalarField> tPn2
|
|
||||||
(
|
|
||||||
mag
|
|
||||||
(
|
|
||||||
fft::reverseTransform
|
|
||||||
(
|
|
||||||
ReComplexField(tpn),
|
|
||||||
labelList(1, tpn().size())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
tpn.clear();
|
|
||||||
|
|
||||||
tmp<scalarField> tPn
|
|
||||||
(
|
|
||||||
new scalarField
|
|
||||||
(
|
|
||||||
scalarField::subField(tPn2(), tPn2().size()/2)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
scalarField& Pn = tPn();
|
|
||||||
|
|
||||||
Pn *= 2.0/sqrt(scalar(tPn2().size()));
|
|
||||||
Pn[0] /= 2.0;
|
|
||||||
|
|
||||||
return tPn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::graph Foam::noiseFFT::meanPf
|
|
||||||
(
|
|
||||||
const label N,
|
|
||||||
const label nw
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (N > size())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Requested window is outside set of data" << nl
|
|
||||||
<< "number of data = " << size() << nl
|
|
||||||
<< "size of window = " << N << nl
|
|
||||||
<< "window = " << nw
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
scalarField MeanPf(N/2, 0.0);
|
|
||||||
|
|
||||||
scalarField Hwf(Hanning(N));
|
|
||||||
|
|
||||||
for (label wi=0; wi<nw; ++wi)
|
|
||||||
{
|
|
||||||
MeanPf += Pf(Hwf*window(N, wi));
|
|
||||||
}
|
|
||||||
|
|
||||||
MeanPf /= nw;
|
|
||||||
|
|
||||||
scalarField f(MeanPf.size());
|
|
||||||
scalar deltaf = 1.0/(N*deltat_);
|
|
||||||
|
|
||||||
forAll(f, i)
|
|
||||||
{
|
|
||||||
f[i] = i*deltaf;
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph
|
|
||||||
(
|
|
||||||
"P(f)",
|
|
||||||
"f [Hz]",
|
|
||||||
"P(f) [Pa]",
|
|
||||||
f,
|
|
||||||
MeanPf
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::graph Foam::noiseFFT::RMSmeanPf
|
|
||||||
(
|
|
||||||
const label N,
|
|
||||||
const label nw
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (N > size())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Requested window is outside set of data" << endl
|
|
||||||
<< "number of data = " << size() << endl
|
|
||||||
<< "size of window = " << N << endl
|
|
||||||
<< "window = " << nw
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
scalarField RMSMeanPf(N/2, 0.0);
|
|
||||||
|
|
||||||
scalarField Hwf(Hanning(N));
|
|
||||||
|
|
||||||
for (label wi=0; wi<nw; ++wi)
|
|
||||||
{
|
|
||||||
RMSMeanPf += sqr(Pf(Hwf*window(N, wi)));
|
|
||||||
}
|
|
||||||
|
|
||||||
RMSMeanPf = sqrt(RMSMeanPf/nw);
|
|
||||||
|
|
||||||
scalarField f(RMSMeanPf.size());
|
|
||||||
scalar deltaf = 1.0/(N*deltat_);
|
|
||||||
|
|
||||||
forAll(f, i)
|
|
||||||
{
|
|
||||||
f[i] = i*deltaf;
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph
|
|
||||||
(
|
|
||||||
"P(f)",
|
|
||||||
"f [Hz]",
|
|
||||||
"P(f) [Pa]",
|
|
||||||
f,
|
|
||||||
RMSMeanPf
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::graph Foam::noiseFFT::Lf(const graph& gPf) const
|
|
||||||
{
|
|
||||||
return graph
|
|
||||||
(
|
|
||||||
"L(f)",
|
|
||||||
"f [Hz]",
|
|
||||||
"L(f) [dB]",
|
|
||||||
gPf.x(),
|
|
||||||
20*log10(gPf.y()/p0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::graph Foam::noiseFFT::Ldelta
|
|
||||||
(
|
|
||||||
const graph& gLf,
|
|
||||||
const scalar f1,
|
|
||||||
const scalar fU
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const scalarField& f = gLf.x();
|
|
||||||
const scalarField& Lf = gLf.y();
|
|
||||||
|
|
||||||
scalarField ldelta(Lf.size(), 0.0);
|
|
||||||
scalarField fm(ldelta.size());
|
|
||||||
|
|
||||||
scalar fratio = cbrt(2.0);
|
|
||||||
scalar deltaf = 1.0/(2*Lf.size()*deltat_);
|
|
||||||
|
|
||||||
scalar fl = f1/sqrt(fratio);
|
|
||||||
scalar fu = fratio*fl;
|
|
||||||
|
|
||||||
label istart = label(fl/deltaf);
|
|
||||||
label j = 0;
|
|
||||||
|
|
||||||
for (label i = istart; i<Lf.size(); i++)
|
|
||||||
{
|
|
||||||
scalar fmi = sqrt(fu*fl);
|
|
||||||
|
|
||||||
if (fmi > fU + 1) break;
|
|
||||||
|
|
||||||
if (f[i] >= fu)
|
|
||||||
{
|
|
||||||
fm[j] = fmi;
|
|
||||||
ldelta[j] = 10*log10(ldelta[j]);
|
|
||||||
|
|
||||||
j++;
|
|
||||||
|
|
||||||
fl = fu;
|
|
||||||
fu *= fratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
ldelta[j] += pow(10, Lf[i]/10.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
fm.setSize(j);
|
|
||||||
ldelta.setSize(j);
|
|
||||||
|
|
||||||
return graph
|
|
||||||
(
|
|
||||||
"Ldelta",
|
|
||||||
"fm [Hz]",
|
|
||||||
"Ldelta [dB]",
|
|
||||||
fm,
|
|
||||||
ldelta
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::graph Foam::noiseFFT::Pdelta
|
|
||||||
(
|
|
||||||
const graph& gPf,
|
|
||||||
const scalar f1,
|
|
||||||
const scalar fU
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const scalarField& f = gPf.x();
|
|
||||||
const scalarField& Pf = gPf.y();
|
|
||||||
|
|
||||||
scalarField pdelta(Pf.size(), 0.0);
|
|
||||||
scalarField fm(pdelta.size());
|
|
||||||
|
|
||||||
scalar fratio = cbrt(2.0);
|
|
||||||
scalar deltaf = 1.0/(2*Pf.size()*deltat_);
|
|
||||||
|
|
||||||
scalar fl = f1/sqrt(fratio);
|
|
||||||
scalar fu = fratio*fl;
|
|
||||||
|
|
||||||
label istart = label(fl/deltaf + 1.0 - SMALL);
|
|
||||||
label j = 0;
|
|
||||||
|
|
||||||
for (label i = istart; i<Pf.size(); i++)
|
|
||||||
{
|
|
||||||
scalar fmi = sqrt(fu*fl);
|
|
||||||
|
|
||||||
if (fmi > fU + 1) break;
|
|
||||||
|
|
||||||
if (f[i] >= fu)
|
|
||||||
{
|
|
||||||
fm[j] = fmi;
|
|
||||||
pdelta[j] = sqrt((2.0/3.0)*pdelta[j]);
|
|
||||||
|
|
||||||
j++;
|
|
||||||
|
|
||||||
fl = fu;
|
|
||||||
fu *= fratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdelta[j] += sqr(Pf[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fm.setSize(j);
|
|
||||||
pdelta.setSize(j);
|
|
||||||
|
|
||||||
return graph
|
|
||||||
(
|
|
||||||
"Pdelta",
|
|
||||||
"fm [Hz]",
|
|
||||||
"Pdelta [dB]",
|
|
||||||
fm,
|
|
||||||
pdelta
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::scalar Foam::noiseFFT::Lsum(const graph& gLf) const
|
|
||||||
{
|
|
||||||
const scalarField& Lf = gLf.y();
|
|
||||||
|
|
||||||
scalar lsum = 0.0;
|
|
||||||
|
|
||||||
forAll(Lf, i)
|
|
||||||
{
|
|
||||||
lsum += pow(10, Lf[i]/10.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
lsum = 10*log10(lsum);
|
|
||||||
|
|
||||||
return lsum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::scalar Foam::noiseFFT::dbToPa(const scalar db) const
|
|
||||||
{
|
|
||||||
return p0*pow(10.0, db/20.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::scalarField> Foam::noiseFFT::dbToPa
|
|
||||||
(
|
|
||||||
const tmp<scalarField>& db
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return p0*pow(10.0, db/20.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
519
src/randomProcesses/noise/noiseFFT/noiseFFT.C
Normal file
519
src/randomProcesses/noise/noiseFFT/noiseFFT.C
Normal file
@ -0,0 +1,519 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "noiseFFT.H"
|
||||||
|
#include "IFstream.H"
|
||||||
|
#include "DynamicList.H"
|
||||||
|
#include "fft.H"
|
||||||
|
#include "SubField.H"
|
||||||
|
#include "mathematicalConstants.H"
|
||||||
|
|
||||||
|
using namespace Foam::constant;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::scalar Foam::noiseFFT::p0 = 2e-5;
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::scalarField> Foam::noiseFFT::frequencies
|
||||||
|
(
|
||||||
|
const label N,
|
||||||
|
const scalar deltaT
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<scalarField> tf(new scalarField(N/2, 0));
|
||||||
|
scalarField& f = tf();
|
||||||
|
|
||||||
|
scalar deltaf = 1.0/(N*deltaT);
|
||||||
|
forAll(f, i)
|
||||||
|
{
|
||||||
|
f[i] = i*deltaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::noiseFFT::octaveFrequenciesIDs
|
||||||
|
(
|
||||||
|
const scalarField& f,
|
||||||
|
const scalar fLower,
|
||||||
|
const scalar fUpper,
|
||||||
|
const scalar octave,
|
||||||
|
labelList& freqBandIDs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Set the indices of to the lower frequency bands for the input frequency
|
||||||
|
// range. Ensure that the centre frequency passes though 1000 Hz
|
||||||
|
|
||||||
|
// Low frequency bound given by:
|
||||||
|
// fLow = f0*(2^(bandI/octave/2))
|
||||||
|
// Centre frequency given by:
|
||||||
|
// fCentre = f0*(2^(bandI/octave))
|
||||||
|
|
||||||
|
scalar f0 = 1000;
|
||||||
|
scalar minFrequency = max(fLower, min(f));
|
||||||
|
|
||||||
|
// Lower frequency band limit
|
||||||
|
label band0Low = ceil(2*octave*log(minFrequency/f0)/log(2.0));
|
||||||
|
|
||||||
|
// Centre frequency band limit
|
||||||
|
//label band0Centre = ceil(octave*log(fLower/f0)/log(2.0));
|
||||||
|
|
||||||
|
scalar fLowerBand = f0*pow(2, band0Low/octave/2);
|
||||||
|
scalar fRatio = pow(2, 1.0/octave);
|
||||||
|
|
||||||
|
bool complete = false;
|
||||||
|
DynamicList<label> bandIDs(f.size());
|
||||||
|
forAll(f, i)
|
||||||
|
{
|
||||||
|
while (f[i] >= fLowerBand)
|
||||||
|
{
|
||||||
|
bandIDs.append(i);
|
||||||
|
fLowerBand *= fRatio;
|
||||||
|
|
||||||
|
if (fLowerBand > fUpper)
|
||||||
|
{
|
||||||
|
complete = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (complete) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
freqBandIDs.transfer(bandIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::scalarField> Foam::noiseFFT::octaveFrequencies
|
||||||
|
(
|
||||||
|
const scalarField& f,
|
||||||
|
const scalar fLower,
|
||||||
|
const scalar fUpper,
|
||||||
|
const scalar octave
|
||||||
|
)
|
||||||
|
{
|
||||||
|
labelList freqBandIDs;
|
||||||
|
octaveFrequenciesIDs(f, fLower, fUpper, octave, freqBandIDs);
|
||||||
|
tmp<scalarField> tf(new scalarField(f, freqBandIDs));
|
||||||
|
return tf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::noiseFFT::noiseFFT
|
||||||
|
(
|
||||||
|
const scalar deltaT,
|
||||||
|
const scalarField& pressure
|
||||||
|
)
|
||||||
|
:
|
||||||
|
scalarField(pressure),
|
||||||
|
deltaT_(deltaT)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::noiseFFT::noiseFFT(const fileName& pFileName, const label skip)
|
||||||
|
:
|
||||||
|
scalarField(),
|
||||||
|
deltaT_(0.0)
|
||||||
|
{
|
||||||
|
// Construct pressure data file
|
||||||
|
IFstream pFile(pFileName);
|
||||||
|
|
||||||
|
// Check pFile stream is OK
|
||||||
|
if (!pFile.good())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot read file " << pFileName
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip)
|
||||||
|
{
|
||||||
|
scalar dummyt, dummyp;
|
||||||
|
|
||||||
|
for (label i = 0; i < skip; i++)
|
||||||
|
{
|
||||||
|
pFile >> dummyt;
|
||||||
|
|
||||||
|
if (!pFile.good() || pFile.eof())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Number of points in file " << pFileName
|
||||||
|
<< " is less than the number to be skipped = " << skip
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
pFile >> dummyp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar t = 0, T0 = 0, T1 = 0;
|
||||||
|
DynamicList<scalar> pData(100000);
|
||||||
|
label i = 0;
|
||||||
|
|
||||||
|
while (!(pFile >> t).eof())
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
T0 = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
T1 = t;
|
||||||
|
pFile >> pData(i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: assumes fixed time step
|
||||||
|
deltaT_ = (T1 - T0)/pData.size();
|
||||||
|
|
||||||
|
this->transfer(pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::graph Foam::noiseFFT::pt() const
|
||||||
|
{
|
||||||
|
scalarField t(size());
|
||||||
|
forAll(t, i)
|
||||||
|
{
|
||||||
|
t[i] = i*deltaT_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"p(t)",
|
||||||
|
"t [s]",
|
||||||
|
"p(t) [Pa]",
|
||||||
|
t,
|
||||||
|
*this
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::scalarField> Foam::noiseFFT::Pf
|
||||||
|
(
|
||||||
|
const tmp<scalarField>& tpn
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
tmp<scalarField> tPn2
|
||||||
|
(
|
||||||
|
mag
|
||||||
|
(
|
||||||
|
fft::reverseTransform
|
||||||
|
(
|
||||||
|
ReComplexField(tpn),
|
||||||
|
labelList(1, tpn().size())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
tpn.clear();
|
||||||
|
|
||||||
|
tmp<scalarField> tPn
|
||||||
|
(
|
||||||
|
new scalarField
|
||||||
|
(
|
||||||
|
scalarField::subField(tPn2(), tPn2().size()/2)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
scalarField& Pn = tPn();
|
||||||
|
|
||||||
|
Pn *= 2.0/sqrt(scalar(tPn2().size()));
|
||||||
|
Pn[0] /= 2.0;
|
||||||
|
|
||||||
|
return tPn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::graph Foam::noiseFFT::meanPf(const windowModel& window) const
|
||||||
|
{
|
||||||
|
const label N = window.nSamples();
|
||||||
|
const label nWindow = window.nWindow();
|
||||||
|
|
||||||
|
scalarField meanPf(N/2, 0.0);
|
||||||
|
|
||||||
|
for (label windowI = 0; windowI < nWindow; ++windowI)
|
||||||
|
{
|
||||||
|
meanPf += Pf(window.apply<scalar>(*this, windowI));
|
||||||
|
}
|
||||||
|
|
||||||
|
meanPf /= scalar(nWindow);
|
||||||
|
|
||||||
|
scalar deltaf = 1.0/(N*deltaT_);
|
||||||
|
scalarField f(meanPf.size());
|
||||||
|
forAll(f, i)
|
||||||
|
{
|
||||||
|
f[i] = i*deltaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"P(f)",
|
||||||
|
"f [Hz]",
|
||||||
|
"P(f) [Pa]",
|
||||||
|
f,
|
||||||
|
meanPf
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::graph Foam::noiseFFT::RMSmeanPf(const windowModel& window) const
|
||||||
|
{
|
||||||
|
const label N = window.nSamples();
|
||||||
|
const label nWindow = window.nWindow();
|
||||||
|
|
||||||
|
scalarField RMSMeanPf(N/2, 0.0);
|
||||||
|
|
||||||
|
for (label windowI = 0; windowI < nWindow; ++windowI)
|
||||||
|
{
|
||||||
|
RMSMeanPf += sqr(Pf(window.apply<scalar>(*this, windowI)));
|
||||||
|
}
|
||||||
|
|
||||||
|
RMSMeanPf = sqrt(RMSMeanPf/scalar(nWindow));
|
||||||
|
|
||||||
|
scalar deltaf = 1.0/(N*deltaT_);
|
||||||
|
scalarField f(RMSMeanPf.size());
|
||||||
|
forAll(f, i)
|
||||||
|
{
|
||||||
|
f[i] = i*deltaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"P(f)",
|
||||||
|
"f [Hz]",
|
||||||
|
"P(f) [Pa]",
|
||||||
|
f,
|
||||||
|
RMSMeanPf
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::graph Foam::noiseFFT::PSDf(const windowModel& window) const
|
||||||
|
{
|
||||||
|
const label N = window.nSamples();
|
||||||
|
const label nWindow = window.nWindow();
|
||||||
|
|
||||||
|
scalarField psd(N/2, 0.0);
|
||||||
|
|
||||||
|
for (label windowI = 0; windowI < nWindow; ++windowI)
|
||||||
|
{
|
||||||
|
psd += 0.5*sqr(Pf(window.apply<scalar>(*this, windowI)));
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar deltaf = 1.0/(N*deltaT_);
|
||||||
|
|
||||||
|
psd /= nWindow*deltaf;
|
||||||
|
|
||||||
|
scalarField f(psd.size());
|
||||||
|
|
||||||
|
forAll(f, i)
|
||||||
|
{
|
||||||
|
f[i] = i*deltaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"PSD(f)",
|
||||||
|
"f [Hz]",
|
||||||
|
"PSD(f) [PaPa_Hz]",
|
||||||
|
f,
|
||||||
|
psd
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::graph Foam::noiseFFT::PSD(const graph& gPSD) const
|
||||||
|
{
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"PSD(dB)",
|
||||||
|
"f [Hz]",
|
||||||
|
"PSD_dB(f) [dB]",
|
||||||
|
gPSD.x(),
|
||||||
|
10*log10(gPSD.y()/sqr(p0))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::graph Foam::noiseFFT::Lf(const graph& gPf) const
|
||||||
|
{
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"L(f)",
|
||||||
|
"f [Hz]",
|
||||||
|
"L(f) [dB]",
|
||||||
|
gPf.x(),
|
||||||
|
20*log10(gPf.y()/p0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::graph Foam::noiseFFT::Ldelta
|
||||||
|
(
|
||||||
|
const graph& gLf,
|
||||||
|
const labelList& freqBandIDs
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (freqBandIDs.size() < 2)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Octave frequency bands are not defined "
|
||||||
|
<< "- skipping Ldelta calculation"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"Ldelta",
|
||||||
|
"fm [Hz]",
|
||||||
|
"Ldelta [dB]",
|
||||||
|
scalarField(),
|
||||||
|
scalarField()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const scalarField& f = gLf.x();
|
||||||
|
const scalarField& Lf = gLf.y();
|
||||||
|
|
||||||
|
scalarField ldelta(freqBandIDs.size() - 1, 0.0);
|
||||||
|
scalarField fm(freqBandIDs.size() -1, 0.0);
|
||||||
|
|
||||||
|
for (label bandI = 0; bandI < freqBandIDs.size() - 1; bandI++)
|
||||||
|
{
|
||||||
|
label f0 = freqBandIDs[bandI];
|
||||||
|
label f1 = freqBandIDs[bandI+1];
|
||||||
|
fm[bandI] = f[f0];
|
||||||
|
|
||||||
|
if (f0 == f1) continue;
|
||||||
|
|
||||||
|
for (label freqI = f0; freqI < f1; freqI++)
|
||||||
|
{
|
||||||
|
ldelta[bandI] += pow(10, Lf[freqI]/10.0);
|
||||||
|
}
|
||||||
|
ldelta[bandI] = 10*log10(ldelta[bandI]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"Ldelta",
|
||||||
|
"fm [Hz]",
|
||||||
|
"Ldelta [dB]",
|
||||||
|
fm,
|
||||||
|
ldelta
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::graph Foam::noiseFFT::Pdelta
|
||||||
|
(
|
||||||
|
const graph& gPf,
|
||||||
|
const labelList& freqBandIDs
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (freqBandIDs.size() < 2)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Octave frequency bands are not defined "
|
||||||
|
<< "- skipping Pdelta calculation"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"Pdelta",
|
||||||
|
"fm [Hz]",
|
||||||
|
"Pdelta [dB]",
|
||||||
|
scalarField(),
|
||||||
|
scalarField()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const scalarField& f = gPf.x();
|
||||||
|
const scalarField& Pf = gPf.y();
|
||||||
|
|
||||||
|
scalarField pdelta(freqBandIDs.size() - 1, 0.0);
|
||||||
|
scalarField fm(pdelta.size());
|
||||||
|
|
||||||
|
for (label bandI = 0; bandI < freqBandIDs.size() - 1; bandI++)
|
||||||
|
{
|
||||||
|
label f0 = freqBandIDs[bandI];
|
||||||
|
label f1 = freqBandIDs[bandI+1];
|
||||||
|
fm[bandI] = f[f0];
|
||||||
|
|
||||||
|
if (f0 == f1) continue;
|
||||||
|
|
||||||
|
for (label freqI = f0; freqI < f1; freqI++)
|
||||||
|
{
|
||||||
|
pdelta[bandI] += sqr(Pf[freqI]);
|
||||||
|
}
|
||||||
|
pdelta[bandI] = sqrt((2.0/3.0)*pdelta[bandI]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph
|
||||||
|
(
|
||||||
|
"Pdelta",
|
||||||
|
"fm [Hz]",
|
||||||
|
"Pdelta [dB]",
|
||||||
|
fm,
|
||||||
|
pdelta
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::noiseFFT::Lsum(const graph& gLf) const
|
||||||
|
{
|
||||||
|
const scalarField& Lf = gLf.y();
|
||||||
|
|
||||||
|
scalar lsum = 0.0;
|
||||||
|
|
||||||
|
forAll(Lf, i)
|
||||||
|
{
|
||||||
|
lsum += pow(10, Lf[i]/10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lsum = 10*log10(lsum);
|
||||||
|
|
||||||
|
return lsum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::noiseFFT::dbToPa(const scalar db) const
|
||||||
|
{
|
||||||
|
return p0*pow(10.0, db/20.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::scalarField> Foam::noiseFFT::dbToPa
|
||||||
|
(
|
||||||
|
const tmp<scalarField>& db
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return p0*pow(10.0, db/20.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -2,8 +2,8 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -25,11 +25,26 @@ Class
|
|||||||
Foam::noiseFFT
|
Foam::noiseFFT
|
||||||
|
|
||||||
Description
|
Description
|
||||||
FFT of the pressure field
|
Performs FFT of pressure field to generate noise data.
|
||||||
|
|
||||||
|
General functionality:
|
||||||
|
- Pf: fft of the pressure data
|
||||||
|
- meanPf: multi-window mean fft
|
||||||
|
- RMSmeanPf: multi-window RMS mean fft
|
||||||
|
- PSDf: multi-window power spectral density (PSD) in frequency domain
|
||||||
|
- PSD: multi-window power spectral density (PSD) in dB
|
||||||
|
- Lf: narrow-band pressure-fluctuation level (PFL) in frequency domain
|
||||||
|
|
||||||
|
Octave-based data:
|
||||||
|
- Ldelta: PFL spectrum
|
||||||
|
- Pdelta: pressure spectrum
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
noiseFFT.C
|
noiseFFT.C
|
||||||
|
|
||||||
|
SeeAlso
|
||||||
|
windowModel.H
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef noiseFFT_H
|
#ifndef noiseFFT_H
|
||||||
@ -37,6 +52,7 @@ SourceFiles
|
|||||||
|
|
||||||
#include "scalarField.H"
|
#include "scalarField.H"
|
||||||
#include "graph.H"
|
#include "graph.H"
|
||||||
|
#include "windowModel.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -54,7 +70,7 @@ class noiseFFT
|
|||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
//- Time spacing of the raw data
|
//- Time spacing of the raw data
|
||||||
scalar deltat_;
|
scalar deltaT_;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -81,34 +97,72 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
//- Return the FFT frequencies
|
||||||
|
static tmp<scalarField> frequencies
|
||||||
|
(
|
||||||
|
const label N,
|
||||||
|
const scalar deltaT
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Return a list of the frequency indices wrt f field that
|
||||||
|
// correspond to the bands limits for a given octave
|
||||||
|
static void octaveFrequenciesIDs
|
||||||
|
(
|
||||||
|
const scalarField& f,
|
||||||
|
const scalar fLower,
|
||||||
|
const scalar fUpper,
|
||||||
|
const scalar octave,
|
||||||
|
labelList& freqBandIDs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Return the 1/octave octave frequency bounds
|
||||||
|
static tmp<scalarField> octaveFrequencies
|
||||||
|
(
|
||||||
|
const scalarField& f,
|
||||||
|
const scalar fLower,
|
||||||
|
const scalar fUpper,
|
||||||
|
const scalar octave
|
||||||
|
);
|
||||||
|
|
||||||
//- Return the graph of p(t)
|
//- Return the graph of p(t)
|
||||||
graph pt() const;
|
graph pt() const;
|
||||||
|
|
||||||
//- Return the nth window
|
|
||||||
tmp<scalarField> window(const label N, const label n) const;
|
|
||||||
|
|
||||||
//- Return the Hanning window function
|
|
||||||
tmp<scalarField> Hanning(const label N) const;
|
|
||||||
|
|
||||||
//- Return the fft of the given pressure data
|
//- Return the fft of the given pressure data
|
||||||
tmp<scalarField> Pf(const tmp<scalarField>& pn) const;
|
tmp<scalarField> Pf(const tmp<scalarField>& pn) const;
|
||||||
|
|
||||||
//- Return the multi-window mean fft of the complete pressure data
|
//- Return the multi-window mean fft of the complete pressure data [Pa]
|
||||||
graph meanPf(const label N, const label nw) const;
|
graph meanPf(const windowModel& window) const;
|
||||||
|
|
||||||
//- Return the multi-window RMS mean fft of the complete pressure data
|
//- Return the multi-window RMS mean fft of the complete pressure
|
||||||
graph RMSmeanPf(const label N, const label nw) const;
|
// data [Pa]
|
||||||
|
graph RMSmeanPf(const windowModel& window) const;
|
||||||
|
|
||||||
//- Return the narrow-band PFL (pressure-fluctuation level) spectrum
|
//- Return the multi-window PSD (power spectral density) of the complete
|
||||||
|
// pressure data [Pa^2/Hz]
|
||||||
|
graph PSDf(const windowModel& window) const;
|
||||||
|
|
||||||
|
//- Return the PSD [dB]
|
||||||
|
graph PSD(const graph& gPSD) const;
|
||||||
|
|
||||||
|
//- Return the narrow-band PFL (pressure-fluctuation level)
|
||||||
|
// spectrum [dB]
|
||||||
graph Lf(const graph& gPf) const;
|
graph Lf(const graph& gPf) const;
|
||||||
|
|
||||||
//- Return the one-third-octave-band PFL spectrum
|
//- Return the octave-band PFL spectrum starting at octave
|
||||||
// starting at octave with mean frequency f1
|
// frequencies given by the supplied frequency bands [dB]
|
||||||
graph Ldelta(const graph& gLf, const scalar f1, const scalar fU) const;
|
graph Ldelta
|
||||||
|
(
|
||||||
|
const graph& gLf,
|
||||||
|
const labelList& freqBandIDs
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Return the one-third-octave-band pressure spectrum
|
//- Return the octave-band pressure spectrum at octave
|
||||||
// starting at octave with mean frequency f1
|
// frequencies given by the supplied frequency bands [dB]
|
||||||
graph Pdelta(const graph& gLf, const scalar f1, const scalar fU) const;
|
graph Pdelta
|
||||||
|
(
|
||||||
|
const graph& gLf,
|
||||||
|
const labelList& freqBandIDs
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Return the total PFL as the sum of Lf over all frequencies
|
//- Return the total PFL as the sum of Lf over all frequencies
|
||||||
scalar Lsum(const graph& gLf) const;
|
scalar Lsum(const graph& gLf) const;
|
||||||
Reference in New Issue
Block a user