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

faceOnlySet.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 "faceOnlySet.H"
00027 #include <meshTools/meshSearch.H>
00028 #include <OpenFOAM/DynamicList.H>
00029 #include <OpenFOAM/polyMesh.H>
00030 
00031 #include <lagrangian/Cloud.H>
00032 #include <lagrangian/passiveParticle.H>
00033 #include <OpenFOAM/IDLList.H>
00034 
00035 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00036 
00037 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00038 
00039 namespace Foam
00040 {
00041     defineTypeNameAndDebug(faceOnlySet, 0);
00042     addToRunTimeSelectionTable(sampledSet, faceOnlySet, word);
00043 }
00044 
00045 
00046 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00047 
00048 
00049 // Sample singly connected segment. Returns false if end_ reached.
00050 bool Foam::faceOnlySet::trackToBoundary
00051 (
00052     Particle<passiveParticle>& singleParticle,
00053     DynamicList<point>& samplingPts,
00054     DynamicList<label>& samplingCells,
00055     DynamicList<label>& samplingFaces,
00056     DynamicList<scalar>& samplingCurveDist
00057 ) const
00058 {
00059     // distance vector between sampling points
00060     const vector offset = end_ - start_;
00061     const vector smallVec = tol*offset;
00062     const scalar smallDist = mag(smallVec);
00063 
00064     // Alias
00065     const point& trackPt = singleParticle.position();
00066 
00067     while(true)
00068     {
00069         point oldPoint = trackPt;
00070 
00071         singleParticle.trackToFace(end_);
00072 
00073         if (singleParticle.face() != -1 && mag(oldPoint - trackPt) > smallDist)
00074         {
00075             // Reached face. Sample.
00076             samplingPts.append(trackPt);
00077             samplingCells.append(singleParticle.cell());
00078             samplingFaces.append(singleParticle.face());
00079             samplingCurveDist.append(mag(trackPt - start_));
00080         }
00081 
00082         if (mag(trackPt - end_) < smallDist)
00083         {
00084             // end reached
00085             return false;
00086         }
00087         else if (singleParticle.onBoundary())
00088         {
00089             // Boundary reached.
00090             return true;
00091         }
00092     }
00093 }
00094 
00095 
00096 void Foam::faceOnlySet::calcSamples
00097 (
00098     DynamicList<point>& samplingPts,
00099     DynamicList<label>& samplingCells,
00100     DynamicList<label>& samplingFaces,
00101     DynamicList<label>& samplingSegments,
00102     DynamicList<scalar>& samplingCurveDist
00103 ) const
00104 {
00105     // distance vector between sampling points
00106     if (mag(end_ - start_) < SMALL)
00107     {
00108         FatalErrorIn("faceOnlySet::calcSamples()")
00109             << "Incorrect sample specification :"
00110             << " start equals end point." << endl
00111             << "  start:" << start_
00112             << "  end:" << end_
00113             << exit(FatalError);
00114     }
00115 
00116     const vector offset = (end_ - start_);
00117     const vector normOffset = offset/mag(offset);
00118     const vector smallVec = tol*offset;
00119     const scalar smallDist = mag(smallVec);
00120 
00121 
00122     // Get all boundary intersections
00123     List<pointIndexHit> bHits = searchEngine().intersections
00124     (
00125         start_ - smallVec,
00126         end_ + smallVec
00127     );
00128 
00129     point bPoint(GREAT, GREAT, GREAT);
00130     label bFaceI = -1;
00131 
00132     if (bHits.size())
00133     {
00134         bPoint = bHits[0].hitPoint();
00135         bFaceI = bHits[0].index();
00136     }
00137 
00138     // Get first tracking point. Use bPoint, bFaceI if provided.
00139 
00140     point trackPt;
00141     label trackCellI = -1;
00142     label trackFaceI = -1;
00143 
00144     //Info<< "before getTrackingPoint : bPoint:" << bPoint
00145     //    << " bFaceI:" << bFaceI << endl;
00146 
00147     getTrackingPoint
00148     (
00149         offset,
00150         start_,
00151         bPoint,
00152         bFaceI,
00153 
00154         trackPt,
00155         trackCellI,
00156         trackFaceI
00157     );
00158 
00159     //Info<< "after getTrackingPoint : "
00160     //    << " trackPt:" << trackPt
00161     //    << " trackCellI:" << trackCellI
00162     //    << " trackFaceI:" << trackFaceI
00163     //    << endl;
00164 
00165     if (trackCellI == -1)
00166     {
00167         // Line start_ - end_ does not intersect domain at all.
00168         // (or is along edge)
00169         // Set points and cell/face labels to empty lists
00170         //Info<< "calcSamples : Both start_ and end_ outside domain"
00171         //    << endl;
00172 
00173         return;
00174     }
00175 
00176     if (trackFaceI == -1)
00177     {
00178         // No boundary face. Check for nearish internal face
00179         trackFaceI = findNearFace(trackCellI, trackPt, smallDist);
00180     }
00181 
00182     //Info<< "calcSamples : got first point to track from :"
00183     //    << "  trackPt:" << trackPt
00184     //    << "  trackCell:" << trackCellI
00185     //    << "  trackFace:" << trackFaceI
00186     //    << endl;
00187 
00188     //
00189     // Track until hit end of all boundary intersections
00190     //
00191 
00192     // current segment number
00193     label segmentI = 0;
00194 
00195     // starting index of current segment in samplePts
00196     label startSegmentI = 0;
00197 
00198     // index in bHits; current boundary intersection
00199     label bHitI = 1;
00200 
00201     while(true)
00202     {
00203         if (trackFaceI != -1)
00204         {
00205             //Info<< "trackPt:" << trackPt << " on face so use." << endl;
00206             samplingPts.append(trackPt);
00207             samplingCells.append(trackCellI);
00208             samplingFaces.append(trackFaceI);
00209             samplingCurveDist.append(mag(trackPt - start_));
00210         }
00211 
00212         // Initialize tracking starting from trackPt
00213         Cloud<passiveParticle> particles(mesh(), IDLList<passiveParticle>());
00214 
00215         passiveParticle singleParticle
00216         (
00217             particles,
00218             trackPt,
00219             trackCellI
00220         );
00221 
00222         bool reachedBoundary = trackToBoundary
00223         (
00224             singleParticle,
00225             samplingPts,
00226             samplingCells,
00227             samplingFaces,
00228             samplingCurveDist
00229         );
00230 
00231         // fill sampleSegments
00232         for(label i = samplingPts.size() - 1; i >= startSegmentI; --i)
00233         {
00234             samplingSegments.append(segmentI);
00235         }
00236 
00237 
00238         if (!reachedBoundary)
00239         {
00240             //Info<< "calcSamples : Reached end of samples: "
00241             //    << "  samplePt now:" << singleParticle.position()
00242             //    << endl;
00243             break;
00244         }
00245 
00246 
00247         // Go past boundary intersection where tracking stopped
00248         // Use coordinate comparison instead of face comparison for
00249         // accuracy reasons
00250 
00251         bool foundValidB = false;
00252 
00253         while (bHitI < bHits.size())
00254         {
00255             scalar dist =
00256                 (bHits[bHitI].hitPoint() - singleParticle.position())
00257               & normOffset;
00258 
00259             //Info<< "Finding next boundary : "
00260             //    << "bPoint:" << bHits[bHitI].hitPoint()
00261             //    << "  tracking:" << singleParticle.position()
00262             //    << "  dist:" << dist
00263             //    << endl;
00264 
00265             if (dist > smallDist)
00266             {
00267                 // hitpoint is past tracking position
00268                 foundValidB = true;
00269                 break;
00270             }
00271             else
00272             {
00273                 bHitI++;
00274             }
00275         }
00276 
00277         if (!foundValidB)
00278         {
00279             // No valid boundary intersection found beyond tracking position
00280             break;
00281         }
00282 
00283         // Update starting point for tracking
00284         trackFaceI = bHits[bHitI].index();
00285         trackPt = pushIn(bHits[bHitI].hitPoint(), trackFaceI);
00286         trackCellI = getBoundaryCell(trackFaceI);
00287 
00288         segmentI++;
00289 
00290         startSegmentI = samplingPts.size();
00291     }
00292 }
00293 
00294 
00295 void Foam::faceOnlySet::genSamples()
00296 {
00297     // Storage for sample points
00298     DynamicList<point> samplingPts;
00299     DynamicList<label> samplingCells;
00300     DynamicList<label> samplingFaces;
00301     DynamicList<label> samplingSegments;
00302     DynamicList<scalar> samplingCurveDist;
00303 
00304     calcSamples
00305     (
00306         samplingPts,
00307         samplingCells,
00308         samplingFaces,
00309         samplingSegments,
00310         samplingCurveDist
00311     );
00312 
00313     samplingPts.shrink();
00314     samplingCells.shrink();
00315     samplingFaces.shrink();
00316     samplingSegments.shrink();
00317     samplingCurveDist.shrink();
00318 
00319     // Copy into *this
00320     setSamples
00321     (
00322         samplingPts,
00323         samplingCells,
00324         samplingFaces,
00325         samplingSegments,
00326         samplingCurveDist
00327     );
00328 }
00329 
00330 
00331 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00332 
00333 Foam::faceOnlySet::faceOnlySet
00334 (
00335     const word& name,
00336     const polyMesh& mesh,
00337     meshSearch& searchEngine,
00338     const word& axis,
00339     const point& start,
00340     const point& end
00341 )
00342 :
00343     sampledSet(name, mesh, searchEngine, axis),
00344     start_(start),
00345     end_(end)
00346 {
00347     genSamples();
00348 
00349     if (debug)
00350     {
00351         write(Info);
00352     }
00353 }
00354 
00355 
00356 Foam::faceOnlySet::faceOnlySet
00357 (
00358     const word& name,
00359     const polyMesh& mesh,
00360     meshSearch& searchEngine,
00361     const dictionary& dict
00362 )
00363 :
00364     sampledSet(name, mesh, searchEngine, dict),
00365     start_(dict.lookup("start")),
00366     end_(dict.lookup("end"))
00367 {
00368     genSamples();
00369 
00370     if (debug)
00371     {
00372         write(Info);
00373     }
00374 }
00375 
00376 
00377 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00378 
00379 Foam::faceOnlySet::~faceOnlySet()
00380 {}
00381 
00382 
00383 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00384 
00385 Foam::point Foam::faceOnlySet::getRefPoint(const List<point>& pts) const
00386 {
00387     return start_;
00388 }
00389 
00390 
00391 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines