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-------------------------------------------------------------------------------
10License
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
36template<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
78template<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
106template<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
148template<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
231template<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
251template<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// ************************************************************************* //
Templated cloud function object base class.
const CloudType & owner() const
Return const access to the owner cloud.
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:75
const fvMesh & mesh() const
Return reference to the mesh.
Definition: DSMCCloudI.H:44
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
const Boundary & boundaryField() const
Return const-reference to the boundary field.
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:65
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
void transfer(List< T > &list)
Definition: List.C:447
void setSize(const label n)
Alias for resize()
Definition: List.H:218
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:175
virtual void postEvolve()
Post-evolve hook.
Output to file stream, using an OSstream.
Definition: OFstream.H:57
Removes parcels that hit user-specified face zone faces.
Definition: RemoveParcels.H:71
void write()
Write post-processing info.
virtual void postFace(const parcelType &p, bool &keepParticle)
Post-face hook.
The TAB Method for Numerical Calculation of Spray Droplet Breakup.
Definition: TAB.H:69
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
bool found(const T &val, label pos=0) const
True if the value if found in the list.
Definition: UListI.H:265
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:525
const MeshType & mesh() const noexcept
Return the mesh reference.
Definition: ZoneMesh.H:142
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Class used to pass data into container.
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:67
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
const labelList & patchID() const
Per boundary face label the patch index.
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:498
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:456
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:75
label whichFace(const label l) const
Return label of face in patch from global face label.
Definition: polyPatch.H:451
label nInternalFaces() const noexcept
Number of internal faces.
Lookup type of boundary radiation properties.
Definition: lookup.H:66
Selector class for relaxation factors, solver type and solution.
Definition: solution.H:66
splitCell * master() const
Definition: splitCell.H:113
bool getModelProperty(const word &entryName, Type &value) const
Retrieve generic property from the sub-model.
const dictionary & coeffDict() const
Return const access to the coefficients dictionary.
Definition: subModelBase.C:131
A class for handling words, derived from Foam::string.
Definition: word.H:68
volScalarField & p
dynamicFvMesh & mesh
OBJstream os(runTime.globalPath()/outputName)
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
const labelIOList & zoneIDs
Definition: correctPhi.H:59
#define DebugInfo
Report an information message using Foam::Info.
type
Types of root.
Definition: Roots.H:55
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:66
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
constexpr char tab
The tab '\t' character(0x09)
Definition: Ostream.H:52
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
Foam::surfaceFields.
mkDir(pdfPath)