pointNoise.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2015-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "pointNoise.H"
29 #include "argList.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 namespace noiseModels
37 {
38 
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 
43 
44 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
45 
47 (
48  const scalarField& t0,
49  const scalarField& p0,
50  scalarField& t,
51  scalarField& p
52 ) const
53 {
54  DynamicList<scalar> tf(t0.size());
55  DynamicList<scalar> pf(t0.size());
56 
57  forAll(t0, timeI)
58  {
59  if (t0[timeI] >= startTime_)
60  {
61  tf.append(t0[timeI]);
62  pf.append(p0[timeI]);
63  }
64  }
65 
66  t.transfer(tf);
67  p.transfer(pf);
68 }
69 
70 
72 (
73  const label dataseti,
74  const Function1Types::CSV<scalar>& data
75 )
76 {
77  if (!Pstream::master())
78  {
79  // Only ever called on master, report if we have odd logic...
81  << "Currently only to be called from master process..." << endl;
82  return;
83  }
84 
85  Info<< "Reading data file: "
86  << fileObr_.time().relativePath(data.fName()) << endl;
87 
88  const word fNameBase(data.fName().stem());
89 
90  // Time and pressure history data
91  scalarField t, p;
92  filterTimeData(data.x(), data.y(), t, p);
93 
94  Info<< " read " << t.size() << " values" << nl << endl;
95 
96  if (!validateBounds(p))
97  {
98  Info<< "No noise data generated" << endl;
99  return;
100  }
101 
102  Info<< "Creating noise FFT" << endl;
103 
104  const scalar deltaT =
105  (
106  sampleFreq_ > 0
107  ? (1.0/sampleFreq_)
109  );
110 
111  // Apply conversions
112  p *= rhoRef_;
113  p -= average(p);
114 
115  // Determine the windowing
116  windowModelPtr_->validate(t.size());
117  const windowModel& win = windowModelPtr_();
118  const scalar deltaf = 1.0/(deltaT*win.nSamples());
119  const fileName outDir(baseFileDir(dataseti)/fNameBase);
120 
121 
122  // Narrow band data
123  // ----------------
124 
125  scalarField f(uniformFrequencies(deltaT, true));
126 
127  // RMS pressure [Pa]
128  if (writePrmsf_)
129  {
130  auto filePtr = newFile(outDir/"Prms_f");
131  auto& os = filePtr();
132 
133  Info<< " Writing " << os.name() << endl;
134 
135  writeFileHeader(os, "f [Hz]", "Prms(f) [Pa]");
137  }
138 
139  // PSD [Pa^2/Hz]
140  const scalarField PSDf(this->PSDf(p, deltaT));
141 
142  if (writePSDf_)
143  {
144  auto filePtr = newFile(outDir/"PSD_f");
145  auto& os = filePtr();
146 
147  Info<< " Writing " << os.relativeName() << endl;
148 
149  writeFileHeader(os, "f [Hz]", "PSD(f) [PaPa_Hz]");
151  }
152 
153  // PSD [dB/Hz]
154  if (writePSD_)
155  {
156  auto filePtr = newFile(outDir/"PSD_dB_Hz_f");
157  auto& os = filePtr();
158 
159  Info<< " Writing " << os.relativeName() << endl;
160 
161  writeFileHeader(os, "f [Hz]", "PSD(f) [dB_Hz]");
163  }
164 
165  // SPL [dB]
166  if (writeSPL_)
167  {
168  auto filePtr = newFile(outDir/"SPL_dB_f");
169  auto& os = filePtr();
170 
171  Info<< " Writing " << os.relativeName() << endl;
172 
174  (
175  os,
176  "f [Hz]",
177  "SPL(f) [" + weightingTypeNames_[SPLweighting_] + "]"
178  );
179  writeFreqDataToFile(os, f, SPL(PSDf*deltaf, f));
180  }
181 
182  if (writeOctaves_)
183  {
184  labelList octave13BandIDs;
185  scalarField octave13FreqCentre;
187  (
188  f,
189  fLower_,
190  fUpper_,
191  3,
192  octave13BandIDs,
193  octave13FreqCentre
194  );
195 
196 
197  // 1/3 octave data
198  // ---------------
199 
200  // Integrated PSD = P(rms)^2 [Pa^2]
201  scalarField Prms13f(octaves(PSDf, f, octave13BandIDs));
202 
203  auto filePtr = newFile(outDir/"SPL13_dB_fm");
204  auto& os = filePtr();
205 
206  Info<< " Writing " << os.relativeName() << endl;
207 
209  (
210  os,
211  "fm [Hz]",
212  "SPL(fm) [" + weightingTypeNames_[SPLweighting_] + "]"
213  );
215  (
216  os,
217  octave13FreqCentre,
218  SPL(Prms13f, octave13FreqCentre)
219  );
220  }
221 }
222 
223 
224 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
225 
227 (
228  const dictionary& dict,
229  const objectRegistry& obr,
230  const word& name,
231  const bool readFields
232 )
233 :
234  noiseModel(dict, obr, name, false)
235 {
236  if (readFields)
237  {
239  }
240 }
241 
242 
243 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
244 
246 {
247  // Point data only handled by master
248  if (!Pstream::master())
249  {
250  return;
251  }
252 
253  forAll(inputFileNames_, filei)
254  {
255  fileName fName = inputFileNames_[filei];
256  fName.expand();
257 
258  if (!fName.isAbsolute())
259  {
260  fName = argList::envGlobalPath()/fName;
261  }
263  Function1Types::CSV<scalar> data("pressure", dict_, nullptr, fName);
264  processData(filei, data);
265  }
266 }
267 
268 
269 bool pointNoise::read(const dictionary& dict)
270 {
271  if (noiseModel::read(dict))
272  {
273  if (!dict.readIfPresent("files", inputFileNames_))
274  {
276 
277  // Note: lookup uses same keyword as used by the CSV constructor
278  dict.readEntry("file", inputFileNames_.first());
279  }
280 
281  return true;
282  }
283 
284  return false;
285 }
286 
287 
288 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
289 
290 } // End namespace noiseModels
291 } // End namespace Foam
292 
293 // ************************************************************************* //
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &f1)
virtual void calculate()
Calculate.
Definition: pointNoise.C:238
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:160
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition: List.C:326
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
Templated CSV function.
Definition: CSV.H:71
autoPtr< windowModel > windowModelPtr_
Window model.
Definition: noiseModel.H:263
pointNoise(const dictionary &dict, const objectRegistry &obr, const word &name=typeName, const bool readFields=true)
Constructor.
Definition: pointNoise.C:220
bool writeOctaves_
Write writeOctaves; default = yes.
Definition: noiseModel.H:319
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
virtual bool read(const dictionary &dict)
Read from dictionary.
Definition: pointNoise.C:262
T & first()
Access first element of the list, position [0].
Definition: UList.H:853
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
fileName relativePath(const fileName &input, const bool caseTag=false) const
Return the input relative to the globalPath by stripping off a leading value of the globalPath...
Definition: TimePathsI.H:103
virtual autoPtr< OFstream > newFile(const fileName &fName) const
Return autoPtr to a new file using file name.
Definition: writeFile.C:82
bool validateBounds(const scalarList &p) const
Return true if all pressure data is within min/max bounds.
Definition: noiseModel.C:216
defineTypeNameAndDebug(pointNoise, 0)
bool writePrmsf_
Write Prmsf; default = yes.
Definition: noiseModel.H:299
Macros for easy insertion into run-time selection tables.
scalar startTime_
Start time, default = 0s.
Definition: noiseModel.H:258
scalar rhoRef_
Reference density (to convert from kinematic to static pressure)
Definition: noiseModel.H:233
void filterTimeData(const scalarField &t0, const scalarField &p0, scalarField &t, scalarField &p) const
Definition: pointNoise.C:40
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
scalar fUpper_
Upper frequency limit, default = 10kHz.
Definition: noiseModel.H:248
scalar checkUniformTimeStep(const scalarList &times) const
Check and return uniform time step.
Definition: noiseModel.C:177
autoPtr< OFstream > filePtr
Definition: createFields.H:37
virtual bool read(const dictionary &dict)
Read from dictionary.
Definition: noiseModel.C:649
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
tmp< scalarField > octaves(const scalarField &data, const scalarField &f, const labelUList &freqBandIDs) const
Generate octave data.
Definition: noiseModel.C:332
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const NameMatchPredicate &selectedFields, DynamicList< regIOobject *> &storedObjects)
Read the selected GeometricFields of the templated type and store on the objectRegistry.
void writeFileHeader(Ostream &os, const string &x, const string &y, const UList< Tuple2< string, token >> &headerValues=UList< Tuple2< string, token >>::null()) const
Write output file header.
Definition: noiseModel.C:250
A class for handling words, derived from Foam::string.
Definition: word.H:63
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const Time & time() const noexcept
Return time registry.
Perform noise analysis on point-based pressure data.
Definition: pointNoise.H:88
static const Enum< weightingType > weightingTypeNames_
Definition: noiseModel.H:190
tmp< scalarField > PSDf(const scalarField &p, const scalar deltaT) const
Return the multi-window Power Spectral Density (PSD) of the complete pressure data [Pa^2/Hz]...
Definition: noiseModel.C:466
virtual tmp< scalarField > x() const
Return the reference values.
Definition: TableBase.C:311
void writeFreqDataToFile(Ostream &os, const scalarField &f, const scalarField &fx) const
Definition: noiseModel.C:278
tmp< Foam::scalarField > PSD(const scalarField &PSDf) const
PSD [dB/Hz].
Definition: noiseModel.C:758
bool writeSPL_
Write SPL; default = yes.
Definition: noiseModel.H:304
virtual tmp< Field< Type > > y() const
Return the dependent values.
Definition: TableBase.C:326
OBJstream os(runTime.globalPath()/outputName)
weightingType SPLweighting_
Weighting.
Definition: noiseModel.H:268
labelList f(nPoints)
fileName baseFileDir() const
Return the base directory for output.
Definition: writeFile.C:43
const dictionary dict_
Copy of dictionary used for construction.
Definition: noiseModel.H:228
static fileName envGlobalPath()
Global case (directory) from environment variable.
Definition: argList.C:651
List< fileName > inputFileNames_
Input file names - optional.
Definition: pointNoise.H:100
#define WarningInFunction
Report a warning using Foam::Warning.
virtual const fileName & fName() const
Return const access to the file name.
Definition: CSV.C:229
static void setOctaveBands(const scalarField &f, const scalar fLower, const scalar fUpper, const scalar octave, labelList &fBandIDs, scalarField &fCentre)
Return a list of the frequency indices wrt f field that correspond to the bands limits for a given oc...
Definition: noiseModel.C:48
bool writePSDf_
Write PSDf; default = yes.
Definition: noiseModel.H:314
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
addToRunTimeSelectionTable(noiseModel, pointNoise, dictionary)
const objectRegistry & fileObr_
Reference to the region objectRegistry.
Definition: writeFile.H:121
tmp< scalarField > SPL(const scalarField &Prms2, const scalar f) const
SPL [dB].
Definition: noiseModel.C:767
messageStream Info
Information stream (stdout output on master, null elsewhere)
bool writePSD_
Write PSD; default = yes.
Definition: noiseModel.H:309
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
Registry of regIOobjects.
void processData(const label dataseti, const Function1Types::CSV< scalar > &data)
Process the CSV data.
Definition: pointNoise.C:65
tmp< scalarField > uniformFrequencies(const scalar deltaT, const bool check) const
Create a field of equally spaced frequencies for the current set of data - assumes a constant time st...
Definition: noiseModel.C:295
scalar sampleFreq_
Prescribed sample frequency.
Definition: noiseModel.H:253
const volScalarField & p0
Definition: EEqn.H:36
tmp< scalarField > RMSmeanPf(const scalarField &p) const
Return the multi-window RMS mean fft of the complete pressure data [Pa].
Definition: noiseModel.C:447
Namespace for OpenFOAM.
scalar fLower_
Lower frequency limit, default = 25Hz.
Definition: noiseModel.H:243
Base class for noise models.
Definition: noiseModel.H:175