FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

KinematicParcel.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "KinematicParcel.H"
00027 
00028 // * * * * * * * * * * *  Protected Member Functions * * * * * * * * * * * * //
00029 
00030 template<class ParcelType>
00031 template<class TrackData>
00032 void Foam::KinematicParcel<ParcelType>::setCellValues
00033 (
00034     TrackData& td,
00035     const scalar dt,
00036     const label cellI
00037 )
00038 {
00039     rhoc_ = td.rhoInterp().interpolate(this->position(), cellI);
00040     if (rhoc_ < td.constProps().rhoMin())
00041     {
00042         WarningIn
00043         (
00044             "void Foam::KinematicParcel<ParcelType>::setCellValues"
00045             "("
00046                 "TrackData&, "
00047                 "const scalar, "
00048                 "const label"
00049             ")"
00050         )   << "Limiting observed density in cell " << cellI << " to "
00051             << td.constProps().rhoMin() <<  nl << endl;
00052 
00053         rhoc_ = td.constProps().rhoMin();
00054     }
00055 
00056     Uc_ = td.UInterp().interpolate(this->position(), cellI);
00057 
00058     muc_ = td.muInterp().interpolate(this->position(), cellI);
00059 
00060     // Apply dispersion components to carrier phase velocity
00061     Uc_ = td.cloud().dispersion().update
00062     (
00063         dt,
00064         cellI,
00065         U_,
00066         Uc_,
00067         UTurb_,
00068         tTurb_
00069     );
00070 }
00071 
00072 
00073 template<class ParcelType>
00074 template<class TrackData>
00075 void Foam::KinematicParcel<ParcelType>::cellValueSourceCorrection
00076 (
00077     TrackData& td,
00078     const scalar dt,
00079     const label cellI
00080 )
00081 {
00082     Uc_ += td.cloud().UTrans()[cellI]/massCell(cellI);
00083 }
00084 
00085 
00086 template<class ParcelType>
00087 template<class TrackData>
00088 void Foam::KinematicParcel<ParcelType>::calc
00089 (
00090     TrackData& td,
00091     const scalar dt,
00092     const label cellI
00093 )
00094 {
00095     // Define local properties at beginning of time step
00096     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00097     const scalar np0 = nParticle_;
00098     const scalar d0 = d_;
00099     const vector U0 = U_;
00100     const scalar rho0 = rho_;
00101     const scalar mass0 = mass();
00102 
00103     // Reynolds number
00104     const scalar Re = this->Re(U0, d0, rhoc_, muc_);
00105 
00106 
00107     // Sources
00108     //~~~~~~~~
00109 
00110     // Explicit momentum source for particle
00111     vector Su = vector::zero;
00112 
00113     // Momentum transfer from the particle to the carrier phase
00114     vector dUTrans = vector::zero;
00115 
00116 
00117     // Motion
00118     // ~~~~~~
00119 
00120     // Calculate new particle velocity
00121     vector U1 =
00122         this->calcVelocity
00123         (
00124             td,
00125             dt,
00126             cellI,
00127             Re,
00128             muc_,
00129             d0,
00130             U0,
00131             rho0,
00132             mass0,
00133             Su,
00134             dUTrans
00135         );
00136 
00137 
00138     // Accumulate carrier phase source terms
00139     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00140     if (td.cloud().coupled())
00141     {
00142         // Update momentum transfer
00143         td.cloud().UTrans()[cellI] += np0*dUTrans;
00144     }
00145 
00146 
00147     // Set new particle properties
00148     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
00149     U_ = U1;
00150 }
00151 
00152 
00153 template<class ParcelType>
00154 template<class TrackData>
00155 const Foam::vector Foam::KinematicParcel<ParcelType>::calcVelocity
00156 (
00157     TrackData& td,
00158     const scalar dt,
00159     const label cellI,
00160     const scalar Re,
00161     const scalar mu,
00162     const scalar d,
00163     const vector& U,
00164     const scalar rho,
00165     const scalar mass,
00166     const vector& Su,
00167     vector& dUTrans
00168 ) const
00169 {
00170     const polyMesh& mesh = this->cloud().pMesh();
00171 
00172     // Momentum transfer coefficient
00173     const scalar utc = td.cloud().drag().utc(Re, d, mu) + ROOTVSMALL;
00174 
00175     // Momentum source due to particle forces
00176     const vector FCoupled =
00177         mass*td.cloud().forces().calcCoupled(cellI, dt, rhoc_, rho, Uc_, U);
00178     const vector FNonCoupled =
00179         mass*td.cloud().forces().calcNonCoupled(cellI, dt, rhoc_, rho, Uc_, U);
00180 
00181 
00182     // New particle velocity
00183     //~~~~~~~~~~~~~~~~~~~~~~
00184 
00185     // Update velocity - treat as 3-D
00186     const scalar As = this->areaS(d);
00187     const vector ap = Uc_ + (FCoupled + FNonCoupled + Su)/(utc*As);
00188     const scalar bp = 6.0*utc/(rho*d);
00189 
00190     IntegrationScheme<vector>::integrationResult Ures =
00191         td.cloud().UIntegrator().integrate(U, dt, ap, bp);
00192 
00193     vector Unew = Ures.value();
00194 
00195     dUTrans += dt*(utc*As*(Ures.average() - Uc_) - FCoupled);
00196 
00197     // Apply correction to velocity and dUTrans for reduced-D cases
00198     meshTools::constrainDirection(mesh, mesh.solutionD(), Unew);
00199     meshTools::constrainDirection(mesh, mesh.solutionD(), dUTrans);
00200 
00201     return Unew;
00202 }
00203 
00204 
00205 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00206 
00207 template <class ParcelType>
00208 Foam::KinematicParcel<ParcelType>::KinematicParcel
00209 (
00210     const KinematicParcel<ParcelType>& p
00211 )
00212 :
00213     Particle<ParcelType>(p),
00214     typeId_(p.typeId_),
00215     nParticle_(p.nParticle_),
00216     d_(p.d_),
00217     U_(p.U_),
00218     rho_(p.rho_),
00219     tTurb_(p.tTurb_),
00220     UTurb_(p.UTurb_),
00221     rhoc_(p.rhoc_),
00222     Uc_(p.Uc_),
00223     muc_(p.muc_)
00224 {}
00225 
00226 
00227 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00228 
00229 template<class ParcelType>
00230 template<class TrackData>
00231 bool Foam::KinematicParcel<ParcelType>::move(TrackData& td)
00232 {
00233     ParcelType& p = static_cast<ParcelType&>(*this);
00234 
00235     td.switchProcessor = false;
00236     td.keepParticle = true;
00237 
00238     const polyMesh& mesh = td.cloud().pMesh();
00239     const polyBoundaryMesh& pbMesh = mesh.boundaryMesh();
00240 
00241     const scalar deltaT = mesh.time().deltaTValue();
00242     scalar tEnd = (1.0 - p.stepFraction())*deltaT;
00243     const scalar dtMax = tEnd;
00244 
00245     while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL)
00246     {
00247         // Apply correction to position for reduced-D cases
00248         meshTools::constrainToMeshCentre(mesh, p.position());
00249 
00250         // Set the Lagrangian time-step
00251         scalar dt = min(dtMax, tEnd);
00252 
00253         // Remember which cell the Parcel is in since this will change if a
00254         // face is hit
00255         label cellI = p.cell();
00256 
00257         if (p.active())
00258         {
00259             dt *= p.trackToFace(p.position() + dt*U_, td);
00260         }
00261 
00262         tEnd -= dt;
00263         p.stepFraction() = 1.0 - tEnd/deltaT;
00264 
00265         // Avoid problems with extremely small timesteps
00266         if (dt > ROOTVSMALL)
00267         {
00268             // Update cell based properties
00269             p.setCellValues(td, dt, cellI);
00270 
00271             if (td.cloud().cellValueSourceCorrection())
00272             {
00273                 p.cellValueSourceCorrection(td, dt, cellI);
00274             }
00275 
00276             p.calc(td, dt, cellI);
00277         }
00278 
00279         if (p.onBoundary() && td.keepParticle)
00280         {
00281             if (isA<processorPolyPatch>(pbMesh[p.patch(p.face())]))
00282             {
00283                 td.switchProcessor = true;
00284             }
00285         }
00286     }
00287 
00288     return td.keepParticle;
00289 }
00290 
00291 
00292 template<class ParcelType>
00293 template<class TrackData>
00294 bool Foam::KinematicParcel<ParcelType>::hitPatch
00295 (
00296     const polyPatch& pp,
00297     TrackData& td,
00298     const label patchI
00299 )
00300 {
00301     ParcelType& p = static_cast<ParcelType&>(*this);
00302     td.cloud().postProcessing().postPatch(p, patchI);
00303 
00304     return td.cloud().patchInteraction().correct
00305     (
00306         pp,
00307         this->face(),
00308         td.keepParticle,
00309         active_,
00310         U_
00311     );
00312 }
00313 
00314 
00315 template<class ParcelType>
00316 bool Foam::KinematicParcel<ParcelType>::hitPatch
00317 (
00318     const polyPatch& pp,
00319     int& td,
00320     const label patchI
00321 )
00322 {
00323     return false;
00324 }
00325 
00326 
00327 template<class ParcelType>
00328 template<class TrackData>
00329 void Foam::KinematicParcel<ParcelType>::hitProcessorPatch
00330 (
00331     const processorPolyPatch&,
00332     TrackData& td
00333 )
00334 {
00335     td.switchProcessor = true;
00336 }
00337 
00338 
00339 template<class ParcelType>
00340 void Foam::KinematicParcel<ParcelType>::hitProcessorPatch
00341 (
00342     const processorPolyPatch&,
00343     int&
00344 )
00345 {}
00346 
00347 
00348 template<class ParcelType>
00349 template<class TrackData>
00350 void Foam::KinematicParcel<ParcelType>::hitWallPatch
00351 (
00352     const wallPolyPatch& wpp,
00353     TrackData& td
00354 )
00355 {
00356     // Wall interactions handled by generic hitPatch function
00357 }
00358 
00359 
00360 template<class ParcelType>
00361 void Foam::KinematicParcel<ParcelType>::hitWallPatch
00362 (
00363     const wallPolyPatch&,
00364     int&
00365 )
00366 {}
00367 
00368 
00369 template<class ParcelType>
00370 template<class TrackData>
00371 void Foam::KinematicParcel<ParcelType>::hitPatch
00372 (
00373     const polyPatch&,
00374     TrackData& td
00375 )
00376 {
00377     td.keepParticle = false;
00378 }
00379 
00380 
00381 template<class ParcelType>
00382 void Foam::KinematicParcel<ParcelType>::hitPatch(const polyPatch&, int&)
00383 {}
00384 
00385 
00386 template<class ParcelType>
00387 void Foam::KinematicParcel<ParcelType>::transformProperties(const tensor& T)
00388 {
00389     Particle<ParcelType>::transformProperties(T);
00390     U_ = transform(T, U_);
00391 }
00392 
00393 
00394 template<class ParcelType>
00395 void Foam::KinematicParcel<ParcelType>::transformProperties
00396 (
00397     const vector& separation
00398 )
00399 {
00400     Particle<ParcelType>::transformProperties(separation);
00401 }
00402 
00403 
00404 // * * * * * * * * * * * * * * IOStream operators  * * * * * * * * * * * * * //
00405 
00406 #include <lagrangianIntermediate/KinematicParcelIO.C>
00407 
00408 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines