PatchParticleHistogram.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) 2020-2021 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 "PatchParticleHistogram.H"
29 #include "Pstream.H"
30 #include "stringListOps.H"
31 #include "ListOps.H"
32 #include "ListListOps.H"
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 template<class CloudType>
38 (
39  const label globalPatchi
40 ) const
41 {
42  return patchIDs_.find(globalPatchi);
43 }
44 
45 
46 // * * * * * * * * * * * * * protected Member Functions * * * * * * * * * * //
47 
48 template<class CloudType>
50 {
51  forAll(times_, i)
52  {
53  List<List<scalar>> procTimes(Pstream::nProcs());
54  procTimes[Pstream::myProcNo()] = times_[i];
55  Pstream::gatherList(procTimes);
56 
57  List<List<scalar>> procDiameters(Pstream::nProcs());
58  procDiameters[Pstream::myProcNo()] = patchDiameters_[i];
59  Pstream::gatherList(procDiameters);
60 
61  List<List<scalar>> procParticles(Pstream::nProcs());
62  procParticles[Pstream::myProcNo()] = patchParticles_[i];
63  Pstream::gatherList(procParticles);
64 
65  if (Pstream::master())
66  {
67  const fvMesh& mesh = this->owner().mesh();
68 
69  mkDir(this->writeTimeDir());
70 
71  const word& patchName = mesh.boundaryMesh()[patchIDs_[i]].name();
72 
73  OFstream patchOutFile
74  (
75  this->writeTimeDir()/patchName + ".post",
76  IOstream::ASCII,
77  IOstream::currentVersion,
78  mesh.time().writeCompression()
79  );
80 
81  List<scalar> globalTimes;
82  globalTimes = ListListOps::combine<List<scalar>>
83  (
84  procTimes,
86  );
87 
88  List<scalar> globalDiameters;
89  globalDiameters = ListListOps::combine<List<scalar>>
90  (
91  procDiameters,
93  );
94 
95  List<scalar> globalParticles;
96  globalParticles = ListListOps::combine<List<scalar>>
97  (
98  procParticles,
100  );
101 
102  // Compute histogram
103  List<scalar> nParticles(nBins_, Zero);
104  forAll(globalDiameters, j)
105  {
106  const label bini = (globalDiameters[j] - min_)/delta_;
107  if (bini >= 0 && bini < nBins_)
108  {
109  nParticles[bini] += globalParticles[j];
110  nParticlesCumulative_[i][bini] += globalParticles[j];
111  }
112  }
113 
114  patchOutFile
115  << "# nBin=" << nBins_
116  << "; min=" << min_
117  << "; max=" << max_ << nl
118  << "# dEdge1 dEdge2 nParticles nParticlesCumulative"
119  << endl;
120 
121  forAll(nParticles, j)
122  {
123  patchOutFile
124  << binEdges_[j]
125  << ' '
126  << binEdges_[j + 1]
127  << ' '
128  << nParticles[j]
129  << ' '
130  << nParticlesCumulative_[i][j]
131  << nl;
132  }
133  }
134 
135  times_[i].clearStorage();
136  patchDiameters_[i].clearStorage();
137  patchParticles_[i].clearStorage();
138  }
139 }
140 
141 
142 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
143 
144 template<class CloudType>
146 (
147  const dictionary& dict,
148  CloudType& owner,
149  const word& modelName
150 )
151 :
152  CloudFunctionObject<CloudType>(dict, owner, modelName, typeName),
153  nBins_(dict.getCheck<label>("nBins", labelMinMax::ge(1))),
154  min_(dict.getScalar("min")),
155  max_(dict.getScalar("max")),
156  delta_((max_ - min_)/scalar(nBins_)),
157  maxStoredParcels_(dict.getScalar("maxStoredParcels")),
158  binEdges_(nBins_ + 1),
159  patchIDs_(),
160  nParticlesCumulative_(),
161  times_(),
162  patchDiameters_(),
163  patchParticles_()
164 {
165  if (min_ >= max_)
166  {
168  << "Histogram minimum = " << min_
169  << ", cannot be larger than histogram maximum = " << max_
170  << exit(FatalIOError);
171  }
172 
173  if (maxStoredParcels_ <= 0)
174  {
176  << "maxStoredParcels = " << maxStoredParcels_
177  << ", cannot be equal to or less than zero"
178  << exit(FatalIOError);
179  }
180 
181  // Compute histogram-bin properties
182  binEdges_[0] = min_;
183  for (label i = 0; i < nBins_; ++i)
184  {
185  const scalar next = min_ + (i+1)*delta_;
186  binEdges_[i+1] = next;
187  }
188 
189  // Compute histogram-patch properties
190  const wordRes patchMatcher(dict.get<wordRes>("patches"));
191 
192  patchIDs_ = patchMatcher.matching(owner.mesh().boundaryMesh().names());
193 
194  if (patchIDs_.empty())
195  {
197  << "No matching patches found: "
198  << flatOutput(patchMatcher) << nl
199  << exit(FatalIOError);
200  }
201 
202  nParticlesCumulative_ =
203  List<List<scalar>>(patchIDs_.size(), List<scalar>(nBins_, Zero));
204 
205  times_.setSize(patchIDs_.size());
206  patchDiameters_.setSize(patchIDs_.size());
207  patchParticles_.setSize(patchIDs_.size());
208 }
209 
210 
211 template<class CloudType>
213 (
215 )
216 :
218  nBins_(ppm.nBins_),
219  min_(ppm.min_),
220  max_(ppm.max_),
221  delta_(ppm.delta_),
222  maxStoredParcels_(ppm.maxStoredParcels_),
223  binEdges_(ppm.binEdges_),
224  patchIDs_(ppm.patchIDs_),
225  nParticlesCumulative_(ppm.nParticlesCumulative_),
226  times_(ppm.times_),
227  patchDiameters_(ppm.patchDiameters_),
228  patchParticles_(ppm.patchParticles_)
229 {}
230 
231 
232 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
233 
234 template<class CloudType>
236 (
237  const parcelType& p,
238  const polyPatch& pp,
239  bool&
240 )
241 {
242  const label patchi = pp.index();
243  const label localPatchi = applyToPatch(patchi);
244 
245  if (localPatchi != -1 && times_[localPatchi].size() < maxStoredParcels_)
246  {
247  times_[localPatchi].append(this->owner().time().value());
248  patchDiameters_[localPatchi].append(p.d());
249  patchParticles_[localPatchi].append(p.nParticle());
250  }
251 }
252 
253 
254 // ************************************************************************* //
Foam::PatchParticleHistogram::postPatch
virtual void postPatch(const parcelType &p, const polyPatch &pp, bool &keepParticle)
Post-patch hook.
Definition: PatchParticleHistogram.C:236
Foam::wordRes::matching
labelList matching(const UList< StringType > &input, const bool invert=false) const
Return list indices for all matches.
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::accessOp
Definition: UList.H:668
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
ListListOps.H
Foam::PatchParticleHistogram::PatchParticleHistogram
PatchParticleHistogram()=delete
No default construct.
Foam::PatchParticleHistogram::write
void write()
Write post-processing info.
Definition: PatchParticleHistogram.C:49
Foam::FatalIOError
IOerror FatalIOError
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::polyBoundaryMesh::names
wordList names() const
Return a list of patch names.
Definition: polyBoundaryMesh.C:555
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::PatchParticleHistogram
Computes a histogram for the distribution of particle diameters and corresponding number of particles...
Definition: PatchParticleHistogram.H:153
Foam::DSMCCloud::mesh
const fvMesh & mesh() const
Return reference to the mesh.
Definition: DSMCCloudI.H:44
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::DSMCCloud
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:71
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Pstream.H
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
PatchParticleHistogram.H
Foam::flatOutput
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:216
Foam::patchIdentifier::index
label index() const noexcept
The index of this patch in the boundaryMesh.
Definition: patchIdentifier.H:147
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::CloudFunctionObject
Templated cloud function object base class.
Definition: CloudFunctionObject.H:62
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
stringListOps.H
Operations on lists of strings.
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
ListOps.H
Various functions to operate on Lists.
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507