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 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 (log_)
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  Info<< 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  Info<< " 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  Info<< 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  log_(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 
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 (label facei : fz)
199  {
200  if (facei < owner.mesh().nInternalFaces())
201  {
202  totArea += magSf[facei];
203  }
204  else
205  {
206  label bFacei = facei - owner.mesh().nInternalFaces();
207  label patchi = pbm.patchID()[bFacei];
208  const polyPatch& pp = pbm[patchi];
209 
210  if
211  (
212  !magSf.boundaryField()[patchi].coupled()
213  || refCast<const coupledPolyPatch>(pp).owner()
214  )
215  {
216  label localFacei = pp.whichFace(facei);
217  totArea += magSf.boundaryField()[patchi][localFacei];
218  }
219  }
220  }
221  totArea = returnReduce(totArea, sumOp<scalar>());
222 
223  makeLogFile(zoneName, i, nFaces, totArea);
224  }
225  }
226 
227  faceZoneIDs_.transfer(zoneIDs);
228 }
229 
230 
231 template<class CloudType>
233 (
234  const RemoveParcels<CloudType>& rpf
235 )
236 :
238  faceZoneIDs_(rpf.faceZoneIDs_),
239  nParcels_(rpf.nParcels_),
240  mass_(rpf.mass_),
241  typeId_(rpf.typeId_),
242  log_(rpf.log_),
243  resetOnWrite_(rpf.resetOnWrite_),
244  resetOnStart_(rpf.resetOnStart_),
245  outputFilePtr_()
246 {}
247 
248 
249 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
250 
251 template<class CloudType>
253 (
254  const parcelType& p,
255  bool& keepParticle
256 )
257 {
258  if ((typeId_ >= 0) && (p.typeId() != typeId_))
259  {
260  // Not processing this particle type
261  return;
262  }
263 
264  if
265  (
266  this->owner().solution().output()
267  || this->owner().solution().transient()
268  )
269  {
270  const faceZoneMesh& fzm = this->owner().mesh().faceZones();
271 
272  forAll(faceZoneIDs_, i)
273  {
274  const faceZone& fz = fzm[faceZoneIDs_[i]];
275  if (fz.found(p.face()))
276  {
277  nParcels_[i]++;
278  mass_[i] += p.mass()*p.nParticle();
279  keepParticle = false;
280  break;
281  }
282  }
283  }
284 }
285 
286 
287 // ************************************************************************* //
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
Foam::RemoveParcels::write
void write()
Write post-processing info.
Definition: RemoveParcels.C:107
Foam::DynamicList< label >
Foam::RemoveParcels::postFace
virtual void postFace(const parcelType &p, bool &keepParticle)
Post-face hook.
Definition: RemoveParcels.C:253
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::RemoveParcels
Removes parcels that hit user-specified face zone faces.
Definition: RemoveParcels.H:68
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
surfaceFields.H
Foam::surfaceFields.
zoneIDs
const labelIOList & zoneIDs
Definition: correctPhi.H:59
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
OFstream.H
Foam::RemoveParcels::RemoveParcels
RemoveParcels(const dictionary &dict, CloudType &owner, const word &modelName)
Construct from dictionary.
Definition: RemoveParcels.C:150
Foam::polyBoundaryMesh::patchID
const labelList & patchID() const
Per boundary face label the patch index.
Definition: polyBoundaryMesh.C:456
Foam::fvMesh::magSf
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
Definition: fvMeshGeometry.C:330
Foam::faceZone
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:64
Foam::DSMCCloud::mesh
const fvMesh & mesh() const
Return reference to the mesh.
Definition: DSMCCloudI.H:44
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::ZoneMesh< faceZone, polyMesh >
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:486
Foam::radiation::lookup
Lookup type of boundary radiation properties.
Definition: lookup.H:63
Foam::DSMCCloud
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:71
RemoveParcels.H
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::RemoveParcels::postEvolve
virtual void postEvolve(const typename parcelType::trackingData &td)
Post-evolve hook.
Definition: RemoveParcels.C:80
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
fvMesh.H
Foam::ZoneMesh::findZoneID
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:519
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:382
Foam::polyPatch::whichFace
label whichFace(const label l) const
Return label of face in patch from global face label.
Definition: polyPatch.H:448
Foam::tab
constexpr char tab
Definition: Ostream.H:403
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const noexcept
Number of internal faces.
Definition: primitiveMeshI.H:78
faceZone.H
Foam::List< scalar >
Foam::CloudFunctionObject
Templated cloud function object base class.
Definition: CloudFunctionObject.H:62
Foam::roots::type
type
Types of root.
Definition: Roots.H:54
Foam::GeometricField< scalar, fvsPatchField, surfaceMesh >
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
Foam::GeometricField::boundaryField
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Definition: GeometricFieldI.H:62