FaceInteraction.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) 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 "FaceInteraction.H"
29 #include "faceZoneMesh.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 template<class CloudType>
36 ({
37  { interactionType::STICK, "stick" },
38  { interactionType::ESCAPE, "escape" },
39  { interactionType::REBOUND, "rebound" },
40 });
41 
42 
43 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
44 
45 template<class CloudType>
47 (
48  const parcelType& p,
49  const label localZonei
50 )
51 {
52  if (!faceZoneBBs_[localZonei].contains(p.position()))
53  {
54  // Quick reject if the particle is not in the face zone bound box
55  return false;
56  }
57 
58  if ((p.d() > dMax_) || (p.d() < dMin_))
59  {
60  return false;
61  }
62 
63  return true;
64 }
65 
66 
67 template<class CloudType>
69 {
70  const fvMesh& mesh = this->owner().mesh();
71  const faceZoneMesh& fzm = mesh.faceZones();
72 
73  Info<< type() << " output:" << nl;
74 
75  // Retrieve any stored data
76  const label nZones = faceZoneIDs_.size();
77  labelList npe0(nZones, Zero);
78  labelList nps0(nZones, Zero);
79  labelList npr0(nZones, Zero);
80 
81  this->getModelProperty("nEscape", npe0);
82  this->getModelProperty("nStick", nps0);
83  this->getModelProperty("nRebound", npr0);
84 
85  // Accumulate current data
86  labelList npe(returnReduce(nEscapeParticles_, sumOp<labelList>()));
87  labelList nps(returnReduce(nStickParticles_, sumOp<labelList>()));
88  labelList npr(returnReduce(nReboundParticles_, sumOp<labelList>()));
89  forAll(npe, i)
90  {
91  npe[i] = npe[i] + npe0[i];
92  nps[i] = nps[i] + nps0[i];
93  npr[i] = npr[i] + npr0[i];
94  }
95 
96 
97  // Write to log/file
98  forAll(faceZoneIDs_, i)
99  {
100  const label zonei = faceZoneIDs_[i];
101  Info<< " Zone : " << fzm[zonei].name() << nl
102  << " Escape : " << npe[i] << nl
103  << " Stick : " << nps[i] << nl
104  << " Rebound : " << npr[i] << nl;
105 
106  if (this->writeToFile())
107  {
108  auto& os = filePtrs_[i];
109 
110  writeCurrentTime(os);
111 
112  // Note - writing as scalar for better formatting
113  os << tab << scalar(npe[i])
114  << tab << scalar(nps[i])
115  << tab << scalar(npr[i])
116  << endl;
117  }
118  }
119  Info<< endl;
120 
121  // Set restart data
122  this->setModelProperty("nEscape", npe);
123  this->setModelProperty("nStick", nps);
124  this->setModelProperty("nRebound", npr);
125 
126  nEscapeParticles_ = Zero;
127  nStickParticles_ = Zero;
128  nReboundParticles_ = Zero;
129 }
130 
131 
132 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
133 
134 template<class CloudType>
136 (
137  const dictionary& dict,
138  CloudType& owner,
139  const word& modelName
140 )
141 :
142  CloudFunctionObject<CloudType>(dict, owner, modelName, typeName),
144  (
145  owner,
146  this->localPath(),
147  typeName,
148  this->coeffDict()
149  ),
150  faceZoneIDs_(),
151  faceZoneBBs_(),
152  faceZoneInteraction_(),
153  filePtrs_(),
154  nEscapeParticles_(),
155  nStickParticles_(),
156  nReboundParticles_(),
157  dMin_(this->coeffDict().getOrDefault("dMin", -GREAT)),
158  dMax_(this->coeffDict().getOrDefault("dMax", GREAT))
159 {
160  const List<Tuple2<word, word>> nameAndInteraction
161  (
162  this->coeffDict().lookup("faceZones")
163  );
164 
165  filePtrs_.setSize(nameAndInteraction.size());
166 
167  faceZoneBBs_.setSize(nameAndInteraction.size());
168  faceZoneInteraction_.setSize(nameAndInteraction.size());
169 
171  const faceZoneMesh& fzm = owner.mesh().faceZones();
172  const auto& faces = this->owner().mesh().faces();
173  const auto& points = this->owner().mesh().points();
174 
175  label nZone = 0;
176  for (const auto& zoneInfo : nameAndInteraction)
177  {
178  const word& zoneName = zoneInfo.first();
179  const label zonei = fzm.findZoneID(zoneName);
180 
181  if (zonei != -1)
182  {
183  zoneIDs.append(zonei);
184  const faceZone& fz = fzm[zonei];
185 
186  const label nFaces = returnReduce(fz.size(), sumOp<label>());
187  Info<< " " << zoneName << " faces: " << nFaces << nl;
188 
189  // Cache the particle action for this faceZone
190  faceZoneInteraction_[nZone] =
191  interactionTypeNames_[zoneInfo.second()];
192 
193  // Cache faceZone bound box
194  auto& bb = faceZoneBBs_[nZone];
195  for (const label facei : fz)
196  {
197  for (const label fpi : faces[facei])
198  {
199  bb.add(points[fpi]);
200  }
201  }
202  reduce(bb.min(), minOp<point>());
203  reduce(bb.max(), maxOp<point>());
204  bb.inflate(0.05);
205 
206  // Create output file for zone
207  if (this->writeToFile())
208  {
209  filePtrs_.set
210  (
211  nZone,
212  this->createFile(modelName + '_' + zoneName)
213  );
214 
215  writeHeaderValue(filePtrs_[nZone], "Source", type());
216  writeHeaderValue(filePtrs_[nZone], "Face zone", zoneName);
217  writeHeaderValue(filePtrs_[nZone], "Faces", nFaces);
218  writeCommented(filePtrs_[nZone], "Time");
219  writeTabbed(filePtrs_[nZone], "Escape");
220  writeTabbed(filePtrs_[nZone], "Stick");
221  writeTabbed(filePtrs_[nZone], "Rebound");
222  filePtrs_[nZone] << nl;
223  }
224  ++nZone;
225  }
226  else
227  {
229  << "Unable to find faceZone " << zoneName
230  << " - removing" << endl;
231  }
232  }
233  faceZoneIDs_.transfer(zoneIDs);
234 
235  filePtrs_.setSize(nZone);
236  faceZoneBBs_.setSize(nZone);
237  faceZoneInteraction_.setSize(nZone);
238  nEscapeParticles_.setSize(nZone, Zero);
239  nStickParticles_.setSize(nZone, Zero);
240  nReboundParticles_.setSize(nZone, Zero);
241 }
242 
243 
244 template<class CloudType>
246 (
247  const FaceInteraction<CloudType>& pfi
248 )
249 :
252  faceZoneIDs_(pfi.faceZoneIDs_),
253  faceZoneBBs_(pfi.faceZoneBBs_),
254  filePtrs_(),
255  nEscapeParticles_(pfi.nEscapeParticles_),
256  nStickParticles_(pfi.nStickParticles_),
257  nReboundParticles_(pfi.nReboundParticles_),
258  dMin_(pfi.dMin_),
259  dMax_(pfi.dMax_)
260 {}
261 
262 
263 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
264 
265 template<class CloudType>
267 (
268  const parcelType& p,
269  bool& keepParticle
270 )
271 {
272  const auto& fzm = this->owner().mesh().faceZones();
273 
274  forAll(faceZoneIDs_, i)
275  {
276  if (!processParticle(p, i))
277  {
278  continue;
279  }
280 
281  const label zonei = faceZoneIDs_[i];
282 
283  const label localFacei = fzm[zonei].find(p.face());
284 
285  if (localFacei != -1)
286  {
287  const label facei = fzm[zonei][localFacei];
288 
289  switch (faceZoneInteraction_[i])
290  {
291  case interactionType::ESCAPE:
292  {
293  keepParticle = false;
294  ++nEscapeParticles_[i];
295  break;
296  }
297  case interactionType::STICK:
298  {
299  auto& pRef = const_cast<parcelType&>(p);
300  pRef.active(false);
301  pRef.U() = Zero;
302  ++nStickParticles_[i];
303  break;
304  }
305  case interactionType::REBOUND:
306  {
307  const face& f = this->owner().mesh().faces()[facei];
308  const auto n = f.unitNormal(this->owner().mesh().points());
309 
310  auto& pRef = const_cast<parcelType&>(p);
311  pRef.U() -= 2*n*(pRef.U() & n);
312  ++nReboundParticles_[i];
313  break;
314  }
315  default:
316  {
318  << "Unhandled enumeration "
319  << interactionTypeNames_[faceZoneInteraction_[i]]
320  << abort(FatalError);
321  }
322  }
323  }
324  }
325 }
326 
327 
328 // ************************************************************************* //
329 
nZones
label nZones
Definition: interpolatedFaces.H:24
Foam::maxOp
Definition: ops.H:223
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1069
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
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::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList< label >
Foam::minOp
Definition: ops.H:224
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
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
FaceInteraction.H
n
label n
Definition: TABSMDCalcMethod2.H:31
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::ZoneMesh< faceZone, polyMesh >
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:486
Foam::FaceInteraction::FaceInteraction
FaceInteraction(const dictionary &dict, CloudType &owner, const word &modelName)
Construct from dictionary.
Definition: FaceInteraction.C:136
Foam::FaceInteraction::postFace
virtual void postFace(const parcelType &p, bool &keepParticle)
Post-face hook.
Definition: FaceInteraction.C:267
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
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FaceInteraction::processParticle
bool processParticle(const parcelType &p, const label localZonei)
Return true if this particle will be assessed.
Definition: FaceInteraction.C:47
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
reduce
reduce(hasMovingMesh, orOp< bool >())
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
faceZoneMesh.H
Foam::faceZoneMesh.
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::ZoneMesh::findZoneID
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:519
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::tab
constexpr char tab
Definition: Ostream.H:403
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::List< label >
Foam::FaceInteraction
Face zone-based particle interactions.
Definition: FaceInteraction.H:81
Foam::CloudFunctionObject
Templated cloud function object base class.
Definition: CloudFunctionObject.H:62
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::roots::type
type
Types of root.
Definition: Roots.H:54
Foam::FaceInteraction::interactionTypeNames_
static const Enum< interactionType > interactionTypeNames_
Names for the interaction types.
Definition: FaceInteraction.H:102
Foam::functionObjects::writeFile
Base class for writing single files from the function objects.
Definition: writeFile.H:119
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::FaceInteraction::write
void write()
Write post-processing info.
Definition: FaceInteraction.C:68
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328