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

ExactParticle.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 <autoMesh/ExactParticle.H>
00027 
00028 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00029 
00030 template<class ParticleType>
00031 template<class TrackingData>
00032 Foam::label Foam::ExactParticle<ParticleType>::track
00033 (
00034     const vector& endPosition,
00035     TrackingData& td
00036 )
00037 {
00038     this->facei_ = -1;
00039 
00040     // Tracks to endPosition or stop on boundary
00041     while (!this->onBoundary() && this->stepFraction_ < 1.0 - SMALL)
00042     {
00043         this->stepFraction_ +=
00044             trackToFace(endPosition, td)
00045            *(1.0 - this->stepFraction_);
00046     }
00047 
00048     return this->facei_;
00049 }
00050 
00051 
00052 template<class ParticleType>
00053 Foam::label Foam::ExactParticle<ParticleType>::track
00054 (
00055     const vector& endPosition
00056 )
00057 {
00058     int dummyTd;
00059     return track(endPosition, dummyTd);
00060 }
00061 
00062 
00063 template<class ParticleType>
00064 template<class TrackingData>
00065 Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
00066 (
00067     const vector& endPosition,
00068     TrackingData& td
00069 )
00070 {
00071     const polyMesh& mesh = this->cloud().pMesh();
00072     const labelList& cFaces = mesh.cells()[this->celli_];
00073 
00074     point intersection(vector::zero);
00075     scalar trackFraction = VGREAT;
00076     label hitFacei = -1;
00077 
00078     const vector vec = endPosition-this->position_;
00079 
00080     forAll(cFaces, i)
00081     {
00082         label facei = cFaces[i];
00083 
00084         if (facei != this->face())
00085         {
00086             pointHit inter = mesh.faces()[facei].intersection
00087             (
00088                 this->position_,
00089                 vec,
00090                 mesh.faceCentres()[facei],
00091                 mesh.points(),
00092                 intersection::HALF_RAY
00093             );
00094 
00095             if (inter.hit() && inter.distance() < trackFraction)
00096             {
00097                 trackFraction = inter.distance();
00098                 hitFacei = facei;
00099                 intersection = inter.hitPoint();
00100             }
00101         }
00102     }
00103 
00104     if (hitFacei == -1)
00105     {
00106         // Did not find any intersection. Fall back to original approximate
00107         // algorithm
00108         return Particle<ParticleType>::trackToFace
00109         (
00110             endPosition,
00111             td
00112         );
00113     }
00114 
00115     if (trackFraction >= (1.0-SMALL))
00116     {
00117         // Nearest intersection beyond endPosition so we hit endPosition.
00118         trackFraction = 1.0;
00119         this->position_ = endPosition;
00120         this->facei_ = -1;
00121         return 1.0;
00122     }
00123     else
00124     {
00125         this->position_ = intersection;
00126         this->facei_ = hitFacei;
00127     }
00128 
00129 
00130     // Normal situation (trackFraction 0..1). Straight copy
00131     // of Particle::trackToFace.
00132 
00133     bool internalFace = this->cloud().internalFace(this->facei_);
00134 
00135     // change cell
00136     if (internalFace) // Internal face
00137     {
00138         if (this->celli_ == mesh.faceOwner()[this->facei_])
00139         {
00140             this->celli_ = mesh.faceNeighbour()[this->facei_];
00141         }
00142         else if (this->celli_ == mesh.faceNeighbour()[this->facei_])
00143         {
00144             this->celli_ = mesh.faceOwner()[this->facei_];
00145         }
00146         else
00147         {
00148             FatalErrorIn
00149             (
00150                 "ExactParticle::trackToFace"
00151                 "(const vector&, TrackingData&)"
00152             )<< "addressing failure" << nl
00153              << abort(FatalError);
00154         }
00155     }
00156     else
00157     {
00158         ParticleType& p = static_cast<ParticleType&>(*this);
00159 
00160         // Soft-sphere algorithm ignores the boundary
00161         if (p.softImpact())
00162         {
00163             trackFraction = 1.0;
00164             this->position_ = endPosition;
00165         }
00166 
00167         label patchi = this->patch(this->facei_);
00168         const polyPatch& patch = mesh.boundaryMesh()[patchi];
00169 
00170         if (isA<wedgePolyPatch>(patch))
00171         {
00172             p.hitWedgePatch
00173             (
00174                 static_cast<const wedgePolyPatch&>(patch), td
00175             );
00176         }
00177         else if (isA<symmetryPolyPatch>(patch))
00178         {
00179             p.hitSymmetryPatch
00180             (
00181                 static_cast<const symmetryPolyPatch&>(patch), td
00182             );
00183         }
00184         else if (isA<cyclicPolyPatch>(patch))
00185         {
00186             p.hitCyclicPatch
00187             (
00188                 static_cast<const cyclicPolyPatch&>(patch), td
00189             );
00190         }
00191         else if (isA<processorPolyPatch>(patch))
00192         {
00193             p.hitProcessorPatch
00194             (
00195                 static_cast<const processorPolyPatch&>(patch), td
00196             );
00197         }
00198         else if (isA<wallPolyPatch>(patch))
00199         {
00200             p.hitWallPatch
00201             (
00202                 static_cast<const wallPolyPatch&>(patch), td
00203             );
00204         }
00205         else if (isA<polyPatch>(patch))
00206         {
00207             p.hitPatch
00208             (
00209                 static_cast<const polyPatch&>(patch), td
00210             );
00211         }
00212         else
00213         {
00214             FatalErrorIn
00215             (
00216                 "ExactParticle::trackToFace"
00217                 "(const vector& endPosition, scalar& trackFraction)"
00218             )<< "patch type " << patch.type() << " not suported" << nl
00219              << abort(FatalError);
00220         }
00221     }
00222 
00223     // If the trackFraction = 0 something went wrong.
00224     // Either the particle is flipping back and forth across a face perhaps
00225     // due to velocity interpolation errors or it is in a "hole" in the mesh
00226     // caused by face warpage.
00227     // In both cases resolve the positional ambiguity by moving the particle
00228     // slightly towards the cell-centre.
00229     if (trackFraction < SMALL)
00230     {
00231         this->position_ +=
00232             1.0e-6*(mesh.cellCentres()[this->celli_] - this->position_);
00233     }
00234 
00235     return trackFraction;
00236 }
00237 
00238 
00239 template<class ParticleType>
00240 Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
00241 (
00242     const vector& endPosition
00243 )
00244 {
00245     int dummyTd;
00246     return trackToFace(endPosition, dummyTd);
00247 }
00248 
00249 
00250 template<class ParticleType>
00251 Foam::Ostream& Foam::operator<<
00252 (
00253     Ostream& os,
00254     const ExactParticle<ParticleType>& p
00255 )
00256 {
00257     return operator<<(os, static_cast<const Particle<ParticleType>&>(p));
00258 }
00259 
00260 
00261 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines