cloudBoundaryCollisionFlux.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "cloud.H"
28 #include "CompactListList.H"
30 #include "functionName.H"
31 #include "functionObject.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 namespace functionObjects
38 {
40 }
41 }
42 
43 
44 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
45 
47 (
48  const word& name,
49  const Time& runTime,
50  const dictionary& dict,
51  const word& phiName,
52  const dimensionSet& phiDims
53 )
54 :
56  prociPtr_(nullptr),
57  faceiPtr_(nullptr),
58  qPtr_(nullptr),
59  phiName_(phiName),
60  phiDims_(phiDims),
61  phib_
62  (
63  mesh().boundary(),
64  surfaceScalarField::Internal::null(),
66  )
67 {}
68 
69 
70 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
71 
73 {}
74 
75 
76 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
77 
79 {
80  return wordList::null();
81 }
82 
83 
85 {
86  return false;
87 }
88 
89 
91 {
92  return true;
93 }
94 
95 
97 {
98  phib_ == Zero;
99 }
100 
101 
103 (
105 )
106 {
107  if (Pstream::parRun())
108  {
109  prociPtr_.set
110  (
112  (
113  IOobject
114  (
115  name() + ":proci",
116  time_.name(),
117  cloud().mesh()
118  ),
119  cloud().mesh(),
121  )
122  );
123  }
124 
125  faceiPtr_.set
126  (
128  (
129  IOobject
130  (
131  name() + ":facei",
132  time_.name(),
133  cloud().mesh()
134  ),
135  cloud().mesh(),
137  )
138  );
139 
140  qPtr_.set
141  (
143  (
144  IOobject
145  (
146  name() + ":q",
147  time_.name(),
148  cloud().mesh()
149  ),
150  cloud().mesh(),
151  dimensionedScalar(phiDims_*dimTime, scalar(0))
152  )
153  );
154 }
155 
156 
158 (
160 )
161 {
162  const LagrangianSubMesh& subMesh = fraction.mesh();
163 
164  if
165  (
166  faceiPtr_.empty()
167  || subMesh.group() == LagrangianGroup::none
168  || subMesh.group() == LagrangianGroup::inInternalMesh
169  ) return;
170 
171  const Foam::cloud& c = cloud();
172 
173  if (Pstream::parRun())
174  {
175  SubField<label> proci(subMesh.sub(prociPtr_->primitiveFieldRef()));
176  proci = Pstream::myProcNo();
177  }
178 
179  SubField<label> facei(subMesh.sub(faceiPtr_->primitiveFieldRef()));
180  facei = subMesh.sub(c.mesh().facei());
181 
182  LagrangianSubScalarSubField q(subMesh.sub(qPtr_()));
183  q += this->q(fraction, +1);
184 }
185 
186 
188 (
190 )
191 {
192  const LagrangianSubMesh& subMesh = fraction.mesh();
193 
194  if
195  (
196  faceiPtr_.empty()
197  || subMesh.group() == LagrangianGroup::none
198  || subMesh.group() == LagrangianGroup::inInternalMesh
199  ) return;
200 
201  const Foam::cloud& c = cloud();
202 
203  auto proci0EqualsProci = [&](const label subi)
204  {
205  if (!Pstream::parRun()) return true;
206 
207  return
208  prociPtr_->primitiveFieldRef()[subi + subMesh.start()]
209  == Pstream::myProcNo();
210  };
211 
212  const SubField<label> facei0 = subMesh.sub(faceiPtr_->primitiveFieldRef());
213  const SubField<label> facei = subMesh.sub(c.mesh().facei());
214 
215  LagrangianSubScalarSubField q(subMesh.sub(qPtr_()));
216  q += this->q(fraction, -1);
217 
219 
220  forAll(subMesh, subi)
221  {
222  // The particle must be on the same face to count as a collision
223  if (!proci0EqualsProci(subi) || facei0[subi] != facei[subi]) continue;
224 
225  const label bFacei = facei[subi] - mesh().nInternalFaces();
226 
227  const labelUList patchis = mesh().polyBFacePatches()[bFacei];
228  const labelUList patchFaceis = mesh().polyBFacePatchFaces()[bFacei];
229 
230  forAll(patchis, i)
231  {
232  const scalar fraction =
233  magSfb[patchis[i]][patchFaceis[i]]
234  /mesh().magFaceAreas()[facei[subi]];
235 
236  phib_[patchis[i]][patchFaceis[i]] +=
237  fraction*q[subi]/time_.deltaTValue();
238  }
239  }
240 }
241 
242 
244 (
246 )
247 {
248  prociPtr_.clear();
249  faceiPtr_.clear();
250  qPtr_.clear();
251 }
252 
253 
255 {
256  return
258  (
259  IOobject
260  (
261  cloud().mesh().name() + ":" + phiName_ + "Coll",
262  time_.name(),
263  mesh(),
266  ),
267  mesh(),
268  phiDims_,
269  scalarField(mesh().nInternalFaces(), scalar(0)),
270  phib_
271  ).write();
272 }
273 
274 
276 {
277  return true;
278 }
279 
280 
281 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Generic GeometricBoundaryField class.
Generic GeometricField class.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
Mesh that relates to a sub-section of a Lagrangian mesh. This is used to construct fields that relate...
LagrangianGroup group() const
Return the group.
word sub(const word &fieldName) const
Return the name of a field corresponding to this sub-mesh.
label start() const
Return start.
static const List< word > & null()
Return a null List.
Definition: ListI.H:118
Pre-declare related SubField type.
Definition: SubField.H:63
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
Foam::calculatedFvsPatchField.
Base class for clouds. Provides a basic evolution algorithm, models, and a database for caching deriv...
Definition: cloud.H:61
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Dimension set for the base types.
Definition: dimensionSet.H:125
Generic dimensioned Type class.
Base class for functions which generate a boundary collision flux for a cloud.
virtual wordList fields() const
Return the list of fields required.
virtual void preCrossFaces(const LagrangianInternalScalarDynamicField &fraction)
Hook before all face crossings.
cloudBoundaryCollisionFlux(const word &name, const Time &runTime, const dictionary &dict, const word &phiName, const dimensionSet &phiDims)
Construct from Time and dictionary.
virtual bool executeAtStart() const
Return false so this function does not execute at the start.
virtual void postCrossFaces(const LagrangianSubScalarSubField &fraction)
Hook following face crossings of a specific sub-mesh.
virtual void preSolve()
Hook before solution steps.
virtual bool execute()
Do nothing. Everything happens in faces crossing hooks.
Base class for function objects that refer to an fvMesh and a cloud. Used, for example,...
Function object that solves for the evolution of a cloud. Only provides one-way coupling with a finit...
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:986
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:1062
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
label nInternalFaces() const
const scalarField & magFaceAreas() const
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
const dimensionedScalar c
Speed of light in a vacuum.
defineTypeNameAndDebug(fvMeshFunctionObject, 0)
const unitSet fraction
Namespace for OpenFOAM.
static const zero Zero
Definition: zero.H:97
const dimensionSet & dimless
Definition: dimensions.C:138
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
SurfaceField< scalar > surfaceScalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const dimensionSet & dimTime
Definition: dimensions.C:142
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
faceListList boundary(nPatches)
dictionary dict