PatchFlowRateInjection.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 | Copyright (C) 2011-2017 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 
26 #include "PatchFlowRateInjection.H"
27 #include "TimeFunction1.H"
28 #include "distributionModel.H"
29 #include "mathematicalConstants.H"
30 #include "surfaceFields.H"
31 
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 
34 template<class CloudType>
36 (
37  const dictionary& dict,
38  CloudType& owner,
39  const word& modelName
40 )
41 :
42  InjectionModel<CloudType>(dict, owner, modelName,typeName),
43  patchInjectionBase(owner.mesh(), this->coeffDict().lookup("patchName")),
44  phiName_(this->coeffDict().template lookupOrDefault<word>("phi", "phi")),
45  rhoName_(this->coeffDict().template lookupOrDefault<word>("rho", "rho")),
46  duration_(readScalar(this->coeffDict().lookup("duration"))),
47  concentration_
48  (
50  (
51  owner.db().time(),
52  "concentration",
53  this->coeffDict()
54  )
55  ),
56  parcelConcentration_
57  (
58  readScalar(this->coeffDict().lookup("parcelConcentration"))
59  ),
60  sizeDistribution_
61  (
63  (
64  this->coeffDict().subDict("sizeDistribution"),
65  owner.rndGen()
66  )
67  )
68 {
69  duration_ = owner.db().time().userTimeToTime(duration_);
70 
71  patchInjectionBase::updateMesh(owner.mesh());
72 
73  // Re-initialise total mass/volume to inject to zero
74  // - will be reset during each injection
75  this->volumeTotal_ = 0.0;
76  this->massTotal_ = 0.0;
77 }
78 
79 
80 template<class CloudType>
82 (
84 )
85 :
88  phiName_(im.phiName_),
89  rhoName_(im.rhoName_),
90  duration_(im.duration_),
91  concentration_(im.concentration_),
92  parcelConcentration_(im.parcelConcentration_),
93  sizeDistribution_(im.sizeDistribution_().clone().ptr())
94 {}
95 
96 
97 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
98 
99 template<class CloudType>
101 {}
102 
103 
104 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
105 
106 template<class CloudType>
108 {
109  patchInjectionBase::updateMesh(this->owner().mesh());
110 }
111 
112 
113 template<class CloudType>
115 {
116  return this->SOI_ + duration_;
117 }
118 
119 
120 template<class CloudType>
122 {
123  const polyMesh& mesh = this->owner().mesh();
124 
125  const surfaceScalarField& phi =
126  mesh.lookupObject<surfaceScalarField>(phiName_);
127 
128  const scalarField& phip = phi.boundaryField()[patchId_];
129 
130  scalar flowRateIn = 0.0;
131  if (phi.dimensions() == dimVelocity*dimArea)
132  {
133  flowRateIn = max(0.0, -sum(phip));
134  }
135  else
136  {
137  const volScalarField& rho =
138  mesh.lookupObject<volScalarField>(rhoName_);
139  const scalarField& rhop = rho.boundaryField()[patchId_];
140 
141  flowRateIn = max(0.0, -sum(phip/rhop));
142  }
143 
144  reduce(flowRateIn, sumOp<scalar>());
145 
146  return flowRateIn;
147 }
148 
149 
150 template<class CloudType>
152 (
153  const scalar time0,
154  const scalar time1
155 )
156 {
157  if ((time0 >= 0.0) && (time0 < duration_))
158  {
159  scalar dt = time1 - time0;
160 
161  scalar c = concentration_.value(0.5*(time0 + time1));
162 
163  scalar nParcels = parcelConcentration_*c*flowRate()*dt;
164 
165  cachedRandom& rnd = this->owner().rndGen();
166 
167  label nParcelsToInject = floor(nParcels);
168 
169  // Inject an additional parcel with a probability based on the
170  // remainder after the floor function
171  if
172  (
173  nParcelsToInject > 0
174  && (
175  nParcels - scalar(nParcelsToInject)
176  > rnd.globalPosition(scalar(0), scalar(1))
177  )
178  )
179  {
180  ++nParcelsToInject;
181  }
182 
183  return nParcelsToInject;
184  }
185  else
186  {
187  return 0;
188  }
189 }
190 
191 
192 template<class CloudType>
194 (
195  const scalar time0,
196  const scalar time1
197 )
198 {
199  scalar volume = 0.0;
200 
201  if ((time0 >= 0.0) && (time0 < duration_))
202  {
203  scalar c = concentration_.value(0.5*(time0 + time1));
204 
205  volume = c*(time1 - time0)*flowRate();
206  }
207 
208  this->volumeTotal_ = volume;
209  this->massTotal_ = volume*this->owner().constProps().rho0();
210 
211  return volume;
212 }
213 
214 
215 template<class CloudType>
217 (
218  const label,
219  const label,
220  const scalar,
221  vector& position,
222  label& cellOwner,
223  label& tetFacei,
224  label& tetPti
225 )
226 {
227  patchInjectionBase::setPositionAndCell
228  (
229  this->owner().mesh(),
230  this->owner().rndGen(),
231  position,
232  cellOwner,
233  tetFacei,
234  tetPti
235  );
236 }
237 
238 
239 template<class CloudType>
241 (
242  const label,
243  const label,
244  const scalar,
245  typename CloudType::parcelType& parcel
246 )
247 {
248  // Set particle velocity to carrier velocity
249  parcel.U() = this->owner().U()[parcel.cell()];
250 
251  // Set particle diameter
252  parcel.d() = sizeDistribution_->sample();
253 }
254 
255 
256 template<class CloudType>
258 {
259  return false;
260 }
261 
262 
263 template<class CloudType>
265 {
266  return true;
267 }
268 
269 
270 // ************************************************************************* //
#define readScalar
Definition: doubleScalar.C:38
Foam::surfaceFields.
surfaceScalarField & phi
dictionary dict
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
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Templated injection model class.
Type globalPosition(const Type &start, const Type &end)
Return a sample between start and end.
Random number generator.
Definition: cachedRandom.H:63
virtual void updateMesh()
Set injector locations when mesh is updated.
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
const dimensionSet & dimensions() const
Return dimensions.
stressControl lookup("compactNormalStress") >> compactNormalStress
dynamicFvMesh & mesh
A class for handling words, derived from string.
Definition: word.H:59
virtual bool validInjection(const label parcelI)
Return flag to identify whether or not injection of parcelI is.
cachedRandom rndGen(label(0), -1)
const Type & value() const
Return const reference to value.
virtual bool fullyDescribed() const
Flag to identify whether model fully describes the parcel.
ParcelType parcelType
Type of parcel the cloud was instantiated for.
Definition: DSMCCloud.H:218
virtual void setPositionAndCell(const label parcelI, const label nParcels, const scalar time, vector &position, label &cellOwner, label &tetFacei, label &tetPti)
Set the injection position and owner cell, tetFace and tetPt.
Patch injection, by using patch flow rate to determine concentration and velocity.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
virtual label parcelsToInject(const scalar time0, const scalar time1)
Number of parcels to introduce relative to SOI.
scalar timeEnd() const
Return the end-of-injection time.
virtual void setProperties(const label parcelI, const label nParcels, const scalar time, typename CloudType::parcelType &parcel)
Set the parcel properties.
PatchFlowRateInjection(const dictionary &dict, CloudType &owner, const word &modelName)
Construct from dictionary.
const dimensionedScalar c
Speed of light in a vacuum.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
virtual scalar volumeToInject(const scalar time0, const scalar time1)
Volume of parcels to introduce relative to SOI.
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:69
virtual scalar flowRate() const
Return the total volumetric flow rate across the patch [m3/s].
virtual ~PatchFlowRateInjection()
Destructor.
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:57
const dimensionSet dimVelocity