RemoveParcels.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-2023 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 "RemoveParcels.H"
29 #include "fvMesh.H"
30 #include "faceZone.H"
31 #include "OFstream.H"
32 #include "surfaceFields.H"
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 template<class CloudType>
38 (
39  const word& zoneName,
40  const label zoneI,
41  const label nFaces,
42  const scalar totArea
43 )
44 {
45  // Create the output file if not already created
46  if (logToFile_)
47  {
48  DebugInfo<< "Creating output file." << endl;
49 
50  if (Pstream::master())
51  {
52  // Create directory if does not exist
53  mkDir(this->writeTimeDir());
54 
55  // Open new file at start up
56  outputFilePtr_.set
57  (
58  zoneI,
59  new OFstream
60  (
61  this->writeTimeDir()/(type() + '_' + zoneName + ".dat")
62  )
63  );
64 
65  outputFilePtr_[zoneI]
66  << "# Source : " << type() << nl
67  << "# Face zone : " << zoneName << nl
68  << "# Faces : " << nFaces << nl
69  << "# Area : " << totArea << nl
70  << "# Time" << tab << "nParcels" << tab << "mass" << endl;
71  }
72  }
73 }
74 
75 
76 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
77 
78 template<class CloudType>
80 (
81  const typename parcelType::trackingData& td
82 )
83 {
84  Log_<< this->modelName() << " output:" << nl;
85 
86  const fvMesh& mesh = this->owner().mesh();
87  const faceZoneMesh& fzm = mesh.faceZones();
88 
89  forAll(faceZoneIDs_, i)
90  {
91  const word& zoneName = fzm[faceZoneIDs_[i]].name();
92 
93  scalar zoneMass = returnReduce(mass_[i], sumOp<scalar>());
94  label zoneNParcels = returnReduce(nParcels_[i], sumOp<label>());
95 
96  Log_<< " faceZone " << zoneName
97  << ": removed " << zoneNParcels
98  << " parcels with mass " << zoneMass
99  << nl;
100  }
101 
103 }
104 
105 
106 template<class CloudType>
108 {
109  const fvMesh& mesh = this->owner().mesh();
110  const Time& time = mesh.time();
111 
112 
113  List<scalar> allZoneMass(faceZoneIDs_.size(), 0.0);
114  List<label> allZoneNParcels(faceZoneIDs_.size(), 0);
115 
116  forAll(faceZoneIDs_, i)
117  {
118  allZoneMass[i] = returnReduce(mass_[i], sumOp<scalar>());
119  allZoneNParcels[i] = returnReduce(nParcels_[i], sumOp<label>());
120 
121  if (outputFilePtr_.set(i))
122  {
123  OFstream& os = outputFilePtr_[i];
124  os << time.timeName() << token::TAB
125  << allZoneNParcels[i] << token::TAB
126  << allZoneMass[i] << endl;
127  }
128  }
129 
130  Log_<< endl;
131 
132  if (resetOnWrite_)
133  {
134  forAll(mass_, i)
135  {
136  mass_[i] = 0.0;
137  nParcels_[i] = 0.0;
138  }
139  }
140 
141  this->setModelProperty("mass", allZoneMass);
142  this->setModelProperty("nParcels", allZoneNParcels);
143 }
144 
145 
146 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
147 
148 template<class CloudType>
150 (
151  const dictionary& dict,
152  CloudType& owner,
153  const word& modelName
154 )
155 :
156  CloudFunctionObject<CloudType>(dict, owner, modelName, typeName),
157  faceZoneIDs_(),
158  nParcels_(),
159  mass_(),
160  typeId_(this->coeffDict().template getOrDefault<label>("parcelType", -1)),
161  logToFile_(this->coeffDict().getBool("log")),
162  resetOnWrite_(this->coeffDict().getBool("resetOnWrite")),
163  resetOnStart_(this->coeffDict().getBool("resetOnStart")),
164  outputFilePtr_()
165 {
166  const wordList faceZoneNames(this->coeffDict().lookup("faceZones"));
167 
168  nParcels_.setSize(faceZoneNames.size(), 0);
169  mass_.setSize(faceZoneNames.size(), 0.0);
170 
171  if (!resetOnStart_ && Pstream::master())
172  {
173  this->getModelProperty("mass", mass_);
174  this->getModelProperty("nParcels", nParcels_);
175  }
176 
177  outputFilePtr_.setSize(faceZoneNames.size());
178 
179  DynamicList<label> zoneIDs;
180  const faceZoneMesh& fzm = owner.mesh().faceZones();
181  const surfaceScalarField& magSf = owner.mesh().magSf();
182  const polyBoundaryMesh& pbm = owner.mesh().boundaryMesh();
183 
184  forAll(faceZoneNames, i)
185  {
186  const word& zoneName = faceZoneNames[i];
187  label zonei = fzm.findZoneID(zoneName);
188 
189  if (zonei != -1)
190  {
191  zoneIDs.append(zonei);
192  const faceZone& fz = fzm[zonei];
193 
194  label nFaces = returnReduce(fz.size(), sumOp<label>());
195  Info<< " " << zoneName << " faces: " << nFaces << nl;
196 
197  scalar totArea = 0.0;
198  for (const label facei : fz)
199  {
200  if (facei < owner.mesh().nInternalFaces())
201  {
202  totArea += magSf[facei];
203  }
204  else
205  {
206  const label patchi = pbm.patchID(facei);
207  const polyPatch& pp = pbm[patchi];
208 
209  if
210  (
211  !magSf.boundaryField()[patchi].coupled()
212  || refCast<const coupledPolyPatch>(pp).owner()
213  )
214  {
215  label localFacei = pp.whichFace(facei);
216  totArea += magSf.boundaryField()[patchi][localFacei];
217  }
218  }
219  }
220  totArea = returnReduce(totArea, sumOp<scalar>());
221 
222  makeLogFile(zoneName, i, nFaces, totArea);
223  }
224  }
226  faceZoneIDs_.transfer(zoneIDs);
227 }
228 
229 
230 template<class CloudType>
232 (
233  const RemoveParcels<CloudType>& rpf
234 )
235 :
237  faceZoneIDs_(rpf.faceZoneIDs_),
238  nParcels_(rpf.nParcels_),
239  mass_(rpf.mass_),
240  typeId_(rpf.typeId_),
241  logToFile_(rpf.logToFile_),
242  resetOnWrite_(rpf.resetOnWrite_),
243  resetOnStart_(rpf.resetOnStart_),
244  outputFilePtr_()
245 {}
246 
247 
248 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
249 
250 template<class CloudType>
252 (
253  const parcelType& p,
254  const typename parcelType::trackingData& td
255 )
256 {
257  bool keepParticle = true;
258 
259  if ((typeId_ >= 0) && (p.typeId() != typeId_))
260  {
261  // Not processing this particle type
262  return keepParticle;
263  }
264 
265  if
266  (
267  this->owner().solution().output()
268  || this->owner().solution().transient()
269  )
270  {
271  const faceZoneMesh& fzm = this->owner().mesh().faceZones();
272 
273  forAll(faceZoneIDs_, i)
274  {
275  const faceZone& fz = fzm[faceZoneIDs_[i]];
276  if (fz.found(p.face()))
277  {
278  nParcels_[i]++;
279  mass_[i] += p.mass()*p.nParticle();
280  keepParticle = false;
281  break;
282  }
283  }
284  }
285 
286  return keepParticle;
287 }
288 
289 
290 // ************************************************************************* //
Foam::surfaceFields.
const polyBoundaryMesh & pbm
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
const labelIOList & zoneIDs
Definition: correctPhi.H:59
type
Types of root.
Definition: Roots.H:52
Removes parcels that hit user-specified face zone faces.
Definition: RemoveParcels.H:64
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
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
constexpr char tab
The tab &#39;\t&#39; character(0x09)
Definition: Ostream.H:49
Lookup type of boundary radiation properties.
Definition: lookup.H:57
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
const CloudType & owner() const
Return const access to the owner cloud.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void setSize(const label n)
Alias for resize()
Definition: List.H:316
dynamicFvMesh & mesh
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:614
#define Log_
Report write to Foam::Info if the class log switch is true.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition: polyMesh.H:608
A class for handling words, derived from Foam::string.
Definition: word.H:63
label nInternalFaces() const noexcept
Number of internal faces.
bool getModelProperty(const word &entryName, Type &value) const
Retrieve generic property from the sub-model.
virtual void postEvolve(const typename parcelType::trackingData &td)
Post-evolve hook.
Definition: RemoveParcels.C:73
const dictionary & coeffDict() const
Return const access to the coefficients dictionary.
Definition: subModelBase.C:122
RemoveParcels(const dictionary &dict, CloudType &owner, const word &modelName)
Construct from dictionary.
#define DebugInfo
Report an information message using Foam::Info.
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
virtual bool postFace(const parcelType &p, const typename parcelType::trackingData &td)
Post-face hook.
OBJstream os(runTime.globalPath()/outputName)
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:670
const fvMesh & mesh() const
Return reference to the mesh.
Definition: DSMCCloudI.H:37
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
void write()
Write post-processing info.
messageStream Info
Information stream (stdout output on master, null elsewhere)
volScalarField & p
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:67
Templated cloud function object base class.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())