mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: Added new surfaceNoise model to process surface data
This commit is contained in:
@ -0,0 +1,490 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
|
||||||
|
\\/ 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 "surfaceNoise.H"
|
||||||
|
#include "surfaceReader.H"
|
||||||
|
#include "surfaceWriter.H"
|
||||||
|
#include "noiseFFT.H"
|
||||||
|
#include "graph.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace noiseModels
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(surfaceNoise, 0);
|
||||||
|
addToRunTimeSelectionTable(noiseModel, surfaceNoise, dictionary);
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
|
||||||
|
|
||||||
|
void surfaceNoise::initialise(const dictionary& dict)
|
||||||
|
{
|
||||||
|
// All reading performed on the master processor only
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
// Create the surface reader
|
||||||
|
const word readerType(dict.lookup("reader"));
|
||||||
|
readerPtr_.reset(surfaceReader::New(readerType, inputFileName_).ptr());
|
||||||
|
|
||||||
|
// Find the index of the pressure data
|
||||||
|
const word pName(dict.lookupOrDefault<word>("pName", "p"));
|
||||||
|
const List<word> fieldNames(readerPtr_->fieldNames(0));
|
||||||
|
pIndex_ = findIndex(fieldNames, pName);
|
||||||
|
if (pIndex_ == -1)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unable to find pressure field name " << pName
|
||||||
|
<< " in list of available fields: " << fieldNames
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the surface writer
|
||||||
|
// - Could be done later, but since this utility can process a lot of
|
||||||
|
// data we can ensure that the user-input is correct prior to doing
|
||||||
|
// the heavy lifting
|
||||||
|
const word writerType(dict.lookup("writer"));
|
||||||
|
dictionary optDict
|
||||||
|
(
|
||||||
|
dict.subOrEmptyDict("writeOptions").subOrEmptyDict(writerType)
|
||||||
|
);
|
||||||
|
writerPtr_.reset(surfaceWriter::New(writerType, optDict).ptr());
|
||||||
|
|
||||||
|
// Set the time range
|
||||||
|
const instantList allTimes = readerPtr_->times();
|
||||||
|
startTimeIndex_ = findStartTimeIndex(allTimes, startTime_);
|
||||||
|
|
||||||
|
// Determine the windowing
|
||||||
|
label nAvailableTimes = allTimes.size() - startTimeIndex_;
|
||||||
|
label nRequiredTimes = windowModelPtr_->validate(nAvailableTimes);
|
||||||
|
|
||||||
|
// Restrict times
|
||||||
|
times_.setSize(nRequiredTimes);
|
||||||
|
forAll(times_, timeI)
|
||||||
|
{
|
||||||
|
times_[timeI] = allTimes[timeI + startTimeIndex_].value();
|
||||||
|
}
|
||||||
|
deltaT_ = checkUniformTimeStep(times_);
|
||||||
|
|
||||||
|
const meshedSurface& surf = readerPtr_->geometry();
|
||||||
|
nFace_ = surf.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
Pstream::scatter(pIndex_);
|
||||||
|
Pstream::scatter(times_);
|
||||||
|
Pstream::scatter(startTimeIndex_);
|
||||||
|
Pstream::scatter(deltaT_);
|
||||||
|
Pstream::scatter(nFace_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void surfaceNoise::readSurfaceData
|
||||||
|
(
|
||||||
|
const labelList& procFaceOffset,
|
||||||
|
List<scalarField>& pData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Data is stored as pressure on surface at a given time. Now we need to
|
||||||
|
// pivot the data so that we have the complete pressure time history per
|
||||||
|
// surface face. In serial mode, this results in all pressure data being
|
||||||
|
// loaded into memory (!)
|
||||||
|
|
||||||
|
Info << "Reading pressure data" << endl;
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
PstreamBuffers pBufs(Pstream::nonBlocking);
|
||||||
|
|
||||||
|
// Procedure:
|
||||||
|
// 1. Master processor reads pressure data for all faces for all times
|
||||||
|
// 2. Master sends each processor a subset of faces
|
||||||
|
// 3. Local processor reconstructs the full time history for the subset
|
||||||
|
// of faces
|
||||||
|
// Note: reading all data on master to avoid potential NFS problems...
|
||||||
|
|
||||||
|
const label myProcI = Pstream::myProcNo();
|
||||||
|
const label nLocalFace =
|
||||||
|
procFaceOffset[myProcI + 1] - procFaceOffset[myProcI];
|
||||||
|
|
||||||
|
// Complete pressure time history data for subset of faces
|
||||||
|
pData.setSize(nLocalFace);
|
||||||
|
const label nTimes = times_.size();
|
||||||
|
forAll(pData, faceI)
|
||||||
|
{
|
||||||
|
pData[faceI].setSize(nTimes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and send data
|
||||||
|
forAll(times_, i)
|
||||||
|
{
|
||||||
|
pBufs.clear();
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
label timeI = i + startTimeIndex_;
|
||||||
|
|
||||||
|
Info<< " time: " << times_[i] << endl;
|
||||||
|
|
||||||
|
// Read pressure at all faces for time timeI
|
||||||
|
scalarField p(readerPtr_->field(timeI, pIndex_, scalar(0)));
|
||||||
|
|
||||||
|
// Send subset of faces to each processor
|
||||||
|
for (label procI = 0; procI < Pstream::nProcs(); procI++)
|
||||||
|
{
|
||||||
|
label face0 = procFaceOffset[procI];
|
||||||
|
label nLocalFace =
|
||||||
|
procFaceOffset[procI + 1] - procFaceOffset[procI];
|
||||||
|
|
||||||
|
UOPstream toProc(procI, pBufs);
|
||||||
|
toProc << SubList<scalar>(p, nLocalFace, face0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pBufs.finishedSends();
|
||||||
|
|
||||||
|
// Receive data from the master
|
||||||
|
UIPstream fromProc(0, pBufs);
|
||||||
|
|
||||||
|
scalarList pSlice(fromProc);
|
||||||
|
|
||||||
|
forAll(pSlice, faceI)
|
||||||
|
{
|
||||||
|
pData[faceI][i] = pSlice[faceI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const label nLocalFace = procFaceOffset[0];
|
||||||
|
|
||||||
|
pData.setSize(nLocalFace);
|
||||||
|
forAll(times_, timeI)
|
||||||
|
{
|
||||||
|
forAll(pData, faceI)
|
||||||
|
{
|
||||||
|
pData[faceI].setSize(times_.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(times_, i)
|
||||||
|
{
|
||||||
|
label timeI = i + startTimeIndex_;
|
||||||
|
|
||||||
|
Info<< " time: " << times_[i] << endl;
|
||||||
|
const scalarField p(readerPtr_->field(timeI, pIndex_, scalar(0)));
|
||||||
|
|
||||||
|
forAll(p, faceI)
|
||||||
|
{
|
||||||
|
pData[faceI][i] = p[faceI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Read "
|
||||||
|
<< returnReduce(pData.size(), sumOp<label>())
|
||||||
|
<< " pressure traces with "
|
||||||
|
<< times_.size()
|
||||||
|
<< " time values" << nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void surfaceNoise::writeSurfaceData
|
||||||
|
(
|
||||||
|
const word& fName,
|
||||||
|
const word& groupName,
|
||||||
|
const word& title,
|
||||||
|
const scalar freq,
|
||||||
|
const scalarField& data,
|
||||||
|
const labelList& procFaceOffset
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
Info<< " processing " << title << " for frequency " << freq << endl;
|
||||||
|
|
||||||
|
fileName outDir
|
||||||
|
(
|
||||||
|
fileName("postProcessing")/"noise"/groupName/Foam::name(freq)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
// Collect the surface data so that we can output the surfaces
|
||||||
|
|
||||||
|
PstreamBuffers pBufs(Pstream::nonBlocking);
|
||||||
|
|
||||||
|
if (!Pstream::master())
|
||||||
|
{
|
||||||
|
UOPstream toProc(0, pBufs);
|
||||||
|
toProc << data;
|
||||||
|
}
|
||||||
|
|
||||||
|
pBufs.finishedSends();
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
const meshedSurface& surf = readerPtr_->geometry();
|
||||||
|
|
||||||
|
scalarField allData(surf.size());
|
||||||
|
|
||||||
|
forAll(data, faceI)
|
||||||
|
{
|
||||||
|
// Master procFaceOffset is zero...
|
||||||
|
allData[faceI] = data[faceI];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||||
|
{
|
||||||
|
UIPstream fromProc(procI, pBufs);
|
||||||
|
scalarList dataSlice(fromProc);
|
||||||
|
forAll(dataSlice, i)
|
||||||
|
{
|
||||||
|
label faceI = procFaceOffset[procI] + i;
|
||||||
|
allData[faceI] = dataSlice[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName outFileName = writerPtr_->write
|
||||||
|
(
|
||||||
|
outDir,
|
||||||
|
fName,
|
||||||
|
surf.points(),
|
||||||
|
surf.faces(),
|
||||||
|
title,
|
||||||
|
allData,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const meshedSurface& surf = readerPtr_->geometry();
|
||||||
|
|
||||||
|
writerPtr_->write
|
||||||
|
(
|
||||||
|
outDir,
|
||||||
|
fName,
|
||||||
|
surf.points(),
|
||||||
|
surf.faces(),
|
||||||
|
title,
|
||||||
|
data,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
surfaceNoise::surfaceNoise(const dictionary& dict)
|
||||||
|
:
|
||||||
|
noiseModel(dict),
|
||||||
|
inputFileName_(dict.lookup("inputFile")),
|
||||||
|
pIndex_(0),
|
||||||
|
times_(),
|
||||||
|
deltaT_(0),
|
||||||
|
startTimeIndex_(0),
|
||||||
|
nFace_(0),
|
||||||
|
fftWriteInterval_(dict.lookupOrDefault("fftWriteInterval", 1))
|
||||||
|
{
|
||||||
|
initialise(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
surfaceNoise::~surfaceNoise()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void surfaceNoise::calculate()
|
||||||
|
{
|
||||||
|
// Container for pressure time history data per face
|
||||||
|
List<scalarField> pData;
|
||||||
|
|
||||||
|
// Processor procFaceOffsets
|
||||||
|
labelList procFaceOffset;
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
const label nProcs = Pstream::nProcs();
|
||||||
|
const label nFacePerProc = floor(nFace_/nProcs) + 1;
|
||||||
|
|
||||||
|
procFaceOffset.setSize(nProcs + 1, 0);
|
||||||
|
for (label i = 1; i < procFaceOffset.size(); i++)
|
||||||
|
{
|
||||||
|
procFaceOffset[i] = min(i*nFacePerProc, nFace_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
procFaceOffset.setSize(1, nFace_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read pressure data from file
|
||||||
|
readSurfaceData(procFaceOffset, pData);
|
||||||
|
|
||||||
|
// Process the pressure data, and store results as surface values per
|
||||||
|
// frequency so that it can be output using the surface writer
|
||||||
|
|
||||||
|
Info<< "Creating noise FFTs" << endl;
|
||||||
|
|
||||||
|
// Storage for FFT data
|
||||||
|
const label nLocalFace = pData.size();
|
||||||
|
const scalarField freq1(noiseFFT::frequencies(nSamples_, deltaT_));
|
||||||
|
const label nFFT = freq1.size()/fftWriteInterval_;
|
||||||
|
List<scalarField> surfPf(nFFT);
|
||||||
|
List<scalarField> surfLf(nFFT);
|
||||||
|
List<scalarField> surfPSD(nFFT);
|
||||||
|
forAll(surfPf, freqI)
|
||||||
|
{
|
||||||
|
surfPf[freqI].setSize(nLocalFace);
|
||||||
|
surfLf[freqI].setSize(nLocalFace);
|
||||||
|
surfPSD[freqI].setSize(nLocalFace);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Storage for 1/3 octave data
|
||||||
|
labelList octave13BandIDs;
|
||||||
|
noiseFFT::octaveFrequenciesIDs(freq1, fLower_, fUpper_, 3, octave13BandIDs);
|
||||||
|
|
||||||
|
List<scalarField> surfPdelta(octave13BandIDs.size() - 1);
|
||||||
|
List<scalarField> surfLdelta(octave13BandIDs.size() - 1);
|
||||||
|
forAll(surfPdelta, freqI)
|
||||||
|
{
|
||||||
|
surfPdelta[freqI].setSize(nLocalFace);
|
||||||
|
surfLdelta[freqI].setSize(nLocalFace);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(pData, faceI)
|
||||||
|
{
|
||||||
|
const scalarField& p = pData[faceI];
|
||||||
|
|
||||||
|
noiseFFT nfft(deltaT_, p);
|
||||||
|
|
||||||
|
nfft -= pRef_;
|
||||||
|
graph Pf(nfft.RMSmeanPf(windowModelPtr_()));
|
||||||
|
graph Lf(nfft.Lf(Pf));
|
||||||
|
graph PSDf(nfft.PSDf(windowModelPtr_()));
|
||||||
|
graph PSD(nfft.PSD(PSDf));
|
||||||
|
|
||||||
|
// Store the frequency results in slot for face of surface
|
||||||
|
forAll(surfPf, i)
|
||||||
|
{
|
||||||
|
label freqI = (i + 1)*fftWriteInterval_ - 1;
|
||||||
|
surfPf[i][faceI] = Pf.y()[freqI];
|
||||||
|
surfLf[i][faceI] = Lf.y()[freqI];
|
||||||
|
surfPSD[i][faceI] = PSD.y()[freqI];
|
||||||
|
}
|
||||||
|
|
||||||
|
graph Pdelta(nfft.Pdelta(Pf, octave13BandIDs));
|
||||||
|
graph Ldelta(nfft.Ldelta(Lf, octave13BandIDs));
|
||||||
|
|
||||||
|
// Store the 1/3 octave results in slot for face of surface
|
||||||
|
forAll(surfPdelta, freqI)
|
||||||
|
{
|
||||||
|
surfPdelta[freqI][faceI] = Pdelta.y()[freqI];
|
||||||
|
surfLdelta[freqI][faceI] = Ldelta.y()[freqI];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the storage for p
|
||||||
|
// p.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Writing fft surface data" << endl;
|
||||||
|
|
||||||
|
forAll(surfPf, i)
|
||||||
|
{
|
||||||
|
label freqI = i*fftWriteInterval_;
|
||||||
|
const word& fName = inputFileName_.name(true);
|
||||||
|
const word gName = "fft";
|
||||||
|
writeSurfaceData
|
||||||
|
(
|
||||||
|
fName,
|
||||||
|
gName,
|
||||||
|
"Pf",
|
||||||
|
freq1[freqI],
|
||||||
|
surfPf[i],
|
||||||
|
procFaceOffset
|
||||||
|
);
|
||||||
|
writeSurfaceData
|
||||||
|
(
|
||||||
|
fName,
|
||||||
|
gName,
|
||||||
|
"Lf",
|
||||||
|
freq1[freqI],
|
||||||
|
surfLf[i],
|
||||||
|
procFaceOffset
|
||||||
|
);
|
||||||
|
writeSurfaceData
|
||||||
|
(
|
||||||
|
fName,
|
||||||
|
gName,
|
||||||
|
"PSD",
|
||||||
|
freq1[freqI],
|
||||||
|
surfPSD[i],
|
||||||
|
procFaceOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Writing one-third octave surface data" << endl;
|
||||||
|
|
||||||
|
forAll(surfPdelta, i)
|
||||||
|
{
|
||||||
|
const word& fName = inputFileName_.name(true);
|
||||||
|
const word gName = "oneThirdOctave";
|
||||||
|
writeSurfaceData
|
||||||
|
(
|
||||||
|
fName,
|
||||||
|
gName,
|
||||||
|
"Pdelta",
|
||||||
|
octave13BandIDs[i],
|
||||||
|
surfPdelta[i],
|
||||||
|
procFaceOffset
|
||||||
|
);
|
||||||
|
writeSurfaceData
|
||||||
|
(
|
||||||
|
fName,
|
||||||
|
gName,
|
||||||
|
"Ldelta",
|
||||||
|
octave13BandIDs[i],
|
||||||
|
surfLdelta[i],
|
||||||
|
procFaceOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace noiseModels
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,201 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
|
||||||
|
\\/ 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::noiseModels::surfaceNoise
|
||||||
|
|
||||||
|
Description
|
||||||
|
Perform noise analysis on surface-based pressure data.
|
||||||
|
|
||||||
|
Input data is read from a dictionary, e.g.
|
||||||
|
|
||||||
|
\verbatim
|
||||||
|
// Pressure reference
|
||||||
|
pRef 0;
|
||||||
|
|
||||||
|
// Number of samples in sampling window
|
||||||
|
// Must be a power of 2, default = 2^16 (=65536)
|
||||||
|
N 4096;
|
||||||
|
|
||||||
|
// Lower frequency bounds
|
||||||
|
fl 25;
|
||||||
|
|
||||||
|
// Upper frequency bounds
|
||||||
|
fu 25;
|
||||||
|
|
||||||
|
// Start time
|
||||||
|
startTime 0;
|
||||||
|
|
||||||
|
windowModel <modelType>
|
||||||
|
<modelType>Coeffs
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input file
|
||||||
|
inputFile "postProcessing/faceSource1/surface/patch/patch.case";
|
||||||
|
|
||||||
|
// Write interval for FFT data, default = 1
|
||||||
|
fftWriteInterval 100;
|
||||||
|
|
||||||
|
// Surface reader
|
||||||
|
reader ensight;
|
||||||
|
|
||||||
|
// Surface writer
|
||||||
|
writer ensight;
|
||||||
|
|
||||||
|
// Collate times for ensight output - ensures geometry is only written once
|
||||||
|
writeOptions
|
||||||
|
{
|
||||||
|
ensight
|
||||||
|
{
|
||||||
|
collateTimes 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
surfaceNoise.C
|
||||||
|
|
||||||
|
SeeAlso
|
||||||
|
noiseModel.H
|
||||||
|
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef surfaceNoise_H
|
||||||
|
#define surfaceNoise_H
|
||||||
|
|
||||||
|
#include "noiseModel.H"
|
||||||
|
#include "labelList.H"
|
||||||
|
#include "scalarField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class surfaceReader;
|
||||||
|
class surfaceWriter;
|
||||||
|
|
||||||
|
namespace noiseModels
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class surfaceNoise Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class surfaceNoise
|
||||||
|
:
|
||||||
|
public noiseModel
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
//- Input file name
|
||||||
|
const fileName inputFileName_;
|
||||||
|
|
||||||
|
//- Index of pressure field in reader field list
|
||||||
|
label pIndex_;
|
||||||
|
|
||||||
|
//- Sample times
|
||||||
|
scalarList times_;
|
||||||
|
|
||||||
|
//- Time step (constant)
|
||||||
|
scalar deltaT_;
|
||||||
|
|
||||||
|
//- Start time index
|
||||||
|
label startTimeIndex_;
|
||||||
|
|
||||||
|
//- Number of surface faces
|
||||||
|
label nFace_;
|
||||||
|
|
||||||
|
//- Frequency data output interval, default = 1
|
||||||
|
// nSamples/2 data points are returned from the FFT, which can
|
||||||
|
// result in a very large number of output files (1 per frequency)
|
||||||
|
label fftWriteInterval_;
|
||||||
|
|
||||||
|
//- Pointer to the surface reader
|
||||||
|
mutable autoPtr<surfaceReader> readerPtr_;
|
||||||
|
|
||||||
|
//- Pointer to the surface writer
|
||||||
|
autoPtr<surfaceWriter> writerPtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Initialise
|
||||||
|
void initialise(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Read surface data
|
||||||
|
void readSurfaceData
|
||||||
|
(
|
||||||
|
const labelList& procFaceOffset,
|
||||||
|
List<scalarField>& pData
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Write surface data to file
|
||||||
|
void writeSurfaceData
|
||||||
|
(
|
||||||
|
const word& fName,
|
||||||
|
const word& groupName,
|
||||||
|
const word& title,
|
||||||
|
const scalar freq,
|
||||||
|
const scalarField& data,
|
||||||
|
const labelList& procFaceOffset
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("surfaceNoise");
|
||||||
|
|
||||||
|
//- Constructor
|
||||||
|
surfaceNoise(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~surfaceNoise();
|
||||||
|
|
||||||
|
|
||||||
|
// Public Member Functions
|
||||||
|
|
||||||
|
//- Calculate
|
||||||
|
virtual void calculate();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace noiseModels
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user