1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "KinematicParcel.H"
29 // * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
31 template<class ParcelType>
32 template<class TrackData>
33 void Foam::KinematicParcel<ParcelType>::setCellValues
40 rhoc_ = td.rhoInterp().interpolate(this->position(), cellI);
41 if (rhoc_ < td.constProps().rhoMin())
45 "void Foam::KinematicParcel<ParcelType>::setCellValues"
51 ) << "Limiting observed density in cell " << cellI << " to "
52 << td.constProps().rhoMin() << nl << endl;
54 rhoc_ = td.constProps().rhoMin();
57 Uc_ = td.UInterp().interpolate(this->position(), cellI);
59 muc_ = td.muInterp().interpolate(this->position(), cellI);
61 // Apply dispersion components to carrier phase velocity
62 Uc_ = td.cloud().dispersion().update
74 template<class ParcelType>
75 template<class TrackData>
76 void Foam::KinematicParcel<ParcelType>::cellValueSourceCorrection
83 Uc_ += td.cloud().UTrans()[cellI]/massCell(cellI);
87 template<class ParcelType>
88 template<class TrackData>
89 void Foam::KinematicParcel<ParcelType>::calc
96 // Define local properties at beginning of time step
97 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
98 const scalar np0 = nParticle_;
100 const vector U0 = U_;
101 const scalar rho0 = rho_;
102 const scalar mass0 = mass();
105 const scalar Re = this->Re(U0, d0, rhoc_, muc_);
111 // Explicit momentum source for particle
112 vector Su = vector::zero;
114 // Momentum transfer from the particle to the carrier phase
115 vector dUTrans = vector::zero;
121 // Calculate new particle velocity
123 calcVelocity(td, dt, cellI, Re, muc_, d0, U0, rho0, mass0, Su, dUTrans);
126 // Accumulate carrier phase source terms
127 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
128 if (td.cloud().coupled())
130 // Update momentum transfer
131 td.cloud().UTrans()[cellI] += np0*dUTrans;
135 // Set new particle properties
136 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
141 template<class ParcelType>
142 template<class TrackData>
143 const Foam::vector Foam::KinematicParcel<ParcelType>::calcVelocity
158 const polyMesh& mesh = this->cloud().pMesh();
160 // Momentum transfer coefficient
161 const scalar utc = td.cloud().drag().utc(Re, d, mu) + ROOTVSMALL;
163 // Momentum source due to particle forces
164 const vector FCoupled =
165 mass*td.cloud().forces().calcCoupled(cellI, dt, rhoc_, rho, Uc_, U);
166 const vector FNonCoupled =
167 mass*td.cloud().forces().calcNonCoupled(cellI, dt, rhoc_, rho, Uc_, U);
170 // New particle velocity
171 //~~~~~~~~~~~~~~~~~~~~~~
173 // Update velocity - treat as 3-D
174 const scalar As = this->areaS(d);
175 const vector ap = Uc_ + (FCoupled + FNonCoupled + Su)/(utc*As);
176 const scalar bp = 6.0*utc/(rho*d);
178 IntegrationScheme<vector>::integrationResult Ures =
179 td.cloud().UIntegrator().integrate(U, dt, ap, bp);
181 vector Unew = Ures.value();
183 dUTrans += dt*(utc*As*(Ures.average() - Uc_) - FCoupled);
185 // Apply correction to velocity and dUTrans for reduced-D cases
186 meshTools::constrainDirection(mesh, mesh.solutionD(), Unew);
187 meshTools::constrainDirection(mesh, mesh.solutionD(), dUTrans);
193 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
195 template <class ParcelType>
196 Foam::KinematicParcel<ParcelType>::KinematicParcel
198 const KinematicParcel<ParcelType>& p
201 Particle<ParcelType>(p),
203 nParticle_(p.nParticle_),
215 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
217 template<class ParcelType>
218 template<class TrackData>
219 bool Foam::KinematicParcel<ParcelType>::move(TrackData& td)
221 ParcelType& p = static_cast<ParcelType&>(*this);
223 td.switchProcessor = false;
224 td.keepParticle = true;
226 const polyMesh& mesh = td.cloud().pMesh();
227 const polyBoundaryMesh& pbMesh = mesh.boundaryMesh();
229 const scalar deltaT = mesh.time().deltaTValue();
230 scalar tEnd = (1.0 - p.stepFraction())*deltaT;
231 const scalar dtMax = tEnd;
233 while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL)
235 // Apply correction to position for reduced-D cases
236 meshTools::constrainToMeshCentre(mesh, p.position());
238 // Set the Lagrangian time-step
239 scalar dt = min(dtMax, tEnd);
241 // Remember which cell the Parcel is in since this will change if a
243 label cellI = p.cell();
245 dt *= p.trackToFace(p.position() + dt*U_, td);
248 p.stepFraction() = 1.0 - tEnd/deltaT;
250 // Avoid problems with extremely small timesteps
253 // Update cell based properties
254 p.setCellValues(td, dt, cellI);
256 if (td.cloud().cellValueSourceCorrection())
258 p.cellValueSourceCorrection(td, dt, cellI);
261 p.calc(td, dt, cellI);
264 if (p.onBoundary() && td.keepParticle)
266 if (isA<processorPolyPatch>(pbMesh[p.patch(p.face())]))
268 td.switchProcessor = true;
273 return td.keepParticle;
277 template<class ParcelType>
278 template<class TrackData>
279 bool Foam::KinematicParcel<ParcelType>::hitPatch
286 ParcelType& p = static_cast<ParcelType&>(*this);
287 td.cloud().postProcessing().postPatch(p, patchI);
289 return td.cloud().patchInteraction().correct
299 template<class ParcelType>
300 bool Foam::KinematicParcel<ParcelType>::hitPatch
311 template<class ParcelType>
312 template<class TrackData>
313 void Foam::KinematicParcel<ParcelType>::hitProcessorPatch
315 const processorPolyPatch&,
319 td.switchProcessor = true;
323 template<class ParcelType>
324 void Foam::KinematicParcel<ParcelType>::hitProcessorPatch
326 const processorPolyPatch&,
332 template<class ParcelType>
333 template<class TrackData>
334 void Foam::KinematicParcel<ParcelType>::hitWallPatch
336 const wallPolyPatch& wpp,
340 // Wall interactions handled by generic hitPatch function
344 template<class ParcelType>
345 void Foam::KinematicParcel<ParcelType>::hitWallPatch
347 const wallPolyPatch&,
353 template<class ParcelType>
354 template<class TrackData>
355 void Foam::KinematicParcel<ParcelType>::hitPatch
361 td.keepParticle = false;
365 template<class ParcelType>
366 void Foam::KinematicParcel<ParcelType>::hitPatch(const polyPatch&, int&)
370 template<class ParcelType>
371 void Foam::KinematicParcel<ParcelType>::transformProperties(const tensor& T)
373 Particle<ParcelType>::transformProperties(T);
374 U_ = transform(T, U_);
378 template<class ParcelType>
379 void Foam::KinematicParcel<ParcelType>::transformProperties
381 const vector& separation
384 Particle<ParcelType>::transformProperties(separation);
388 // * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * * * //
390 #include "KinematicParcelIO.C"
392 // ************************************************************************* //