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

curveSet.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 "curveSet.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(curveSet, 0);
00042     addToRunTimeSelectionTable(sampledSet, curveSet, word);
00043 }
00044 
00045 
00046 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00047 
00048 // Sample till hits boundary.
00049 bool Foam::curveSet::trackToBoundary
00050 (
00051     Particle<passiveParticle>& singleParticle,
00052     label& sampleI,
00053     DynamicList<point>& samplingPts,
00054     DynamicList<label>& samplingCells,
00055     DynamicList<label>& samplingFaces,
00056     DynamicList<scalar>& samplingCurveDist
00057 ) const
00058 {
00059     // Alias
00060     const point& trackPt = singleParticle.position();
00061 
00062     while(true)
00063     {
00064         // Local geometry info
00065         const vector offset = sampleCoords_[sampleI+1] - sampleCoords_[sampleI];
00066         const scalar smallDist = mag(tol*offset);
00067 
00068         point oldPos = trackPt;
00069         label facei = -1;
00070         do
00071         {
00072             singleParticle.stepFraction() = 0;
00073             singleParticle.track(sampleCoords_[sampleI+1]);
00074         }
00075         while
00076         (
00077             !singleParticle.onBoundary()
00078          && (mag(trackPt - oldPos) < smallDist)
00079         );
00080 
00081         if (singleParticle.onBoundary())
00082         {
00083             //Info<< "trackToBoundary : reached boundary"
00084             //    << "  trackPt:" << trackPt << endl;
00085             if
00086             (
00087                 mag(trackPt - sampleCoords_[sampleI+1])
00088               < smallDist
00089             )
00090             {
00091                 // Reached samplePt on boundary
00092                 //Info<< "trackToBoundary : boundary. also sampling."
00093                 //    << "  trackPt:" << trackPt << " sampleI+1:" << sampleI+1
00094                 //    << endl;
00095                 samplingPts.append(trackPt);
00096                 samplingCells.append(singleParticle.cell());
00097                 samplingFaces.append(facei);
00098 
00099                 // trackPt is at sampleI+1
00100                 samplingCurveDist.append(1.0*(sampleI+1));
00101             }
00102             return true;
00103         }
00104 
00105         // Reached samplePt in cell
00106         samplingPts.append(trackPt);
00107         samplingCells.append(singleParticle.cell());
00108         samplingFaces.append(-1);
00109 
00110         // Convert trackPt to fraction inbetween sampleI and sampleI+1
00111         scalar dist =
00112             mag(trackPt - sampleCoords_[sampleI])
00113           / mag(sampleCoords_[sampleI+1] - sampleCoords_[sampleI]);
00114         samplingCurveDist.append(sampleI + dist);
00115 
00116         // go to next samplePt
00117         sampleI++;
00118 
00119         if (sampleI == sampleCoords_.size() - 1)
00120         {
00121             // no more samples.
00122             //Info<< "trackToBoundary : Reached end : sampleI now:" << sampleI
00123             //    << endl;
00124             return false;
00125         }
00126     }
00127 }
00128 
00129 
00130 void Foam::curveSet::calcSamples
00131 (
00132     DynamicList<point>& samplingPts,
00133     DynamicList<label>& samplingCells,
00134     DynamicList<label>& samplingFaces,
00135     DynamicList<label>& samplingSegments,
00136     DynamicList<scalar>& samplingCurveDist
00137 ) const
00138 {
00139     // Check sampling points
00140     if (sampleCoords_.size() < 2)
00141     {
00142         FatalErrorIn("curveSet::calcSamples()")
00143             << "Incorrect sample specification. Too few points:"
00144             << sampleCoords_ << exit(FatalError);
00145     }
00146     point oldPoint = sampleCoords_[0];
00147     for(label sampleI = 1; sampleI < sampleCoords_.size(); sampleI++)
00148     {
00149         if (mag(sampleCoords_[sampleI] - oldPoint) < SMALL)
00150         {
00151             FatalErrorIn("curveSet::calcSamples()")
00152                 << "Incorrect sample specification."
00153                 << " Point " << sampleCoords_[sampleI-1]
00154                 << " at position " << sampleI-1
00155                 << " and point " << sampleCoords_[sampleI]
00156                 << " at position " << sampleI
00157                 << " are too close" << exit(FatalError);
00158         }
00159         oldPoint = sampleCoords_[sampleI];
00160     }
00161 
00162     // current segment number
00163     label segmentI = 0;
00164 
00165     // starting index of current segment in samplePts
00166     label startSegmentI = 0;
00167 
00168     label sampleI = 0;
00169 
00170     point lastSample(GREAT, GREAT, GREAT);
00171     while(true)
00172     {
00173         // Get boundary intersection
00174         point trackPt;
00175         label trackCellI = -1;
00176         label trackFaceI = -1;
00177 
00178         do
00179         {
00180             const vector offset =
00181                 sampleCoords_[sampleI+1] - sampleCoords_[sampleI];
00182             const scalar smallDist = mag(tol*offset);
00183 
00184 
00185             // Get all boundary intersections
00186             List<pointIndexHit> bHits = searchEngine().intersections
00187             (
00188                 sampleCoords_[sampleI],
00189                 sampleCoords_[sampleI+1]
00190             );
00191 
00192             point bPoint(GREAT, GREAT, GREAT);
00193             label bFaceI = -1;
00194 
00195             if (bHits.size())
00196             {
00197                 bPoint = bHits[0].hitPoint();
00198                 bFaceI = bHits[0].index();
00199             }
00200 
00201             // Get tracking point
00202 
00203             bool isSample =
00204                 getTrackingPoint
00205                 (
00206                     sampleCoords_[sampleI+1] - sampleCoords_[sampleI],
00207                     sampleCoords_[sampleI],
00208                     bPoint,
00209                     bFaceI,
00210 
00211                     trackPt,
00212                     trackCellI,
00213                     trackFaceI
00214                 );
00215 
00216             if (isSample && (mag(lastSample - trackPt) > smallDist))
00217             {
00218                 //Info<< "calcSamples : getTrackingPoint returned valid sample "
00219                 //    << "  trackPt:" << trackPt
00220                 //    << "  trackFaceI:" << trackFaceI
00221                 //    << "  trackCellI:" << trackCellI
00222                 //    << "  sampleI:" << sampleI
00223                 //    << "  dist:" << dist
00224                 //    << endl;
00225 
00226                 samplingPts.append(trackPt);
00227                 samplingCells.append(trackCellI);
00228                 samplingFaces.append(trackFaceI);
00229 
00230                 // Convert sampling position to unique curve parameter. Get
00231                 // fraction of distance between sampleI and sampleI+1.
00232                 scalar dist =
00233                     mag(trackPt - sampleCoords_[sampleI])
00234                   / mag(sampleCoords_[sampleI+1] - sampleCoords_[sampleI]);
00235                 samplingCurveDist.append(sampleI + dist);
00236 
00237                 lastSample = trackPt;
00238             }
00239 
00240             if (trackCellI == -1)
00241             {
00242                 // No intersection found. Go to next point
00243                 sampleI++;
00244             }
00245         } while((trackCellI == -1) && (sampleI < sampleCoords_.size() - 1));
00246 
00247         if (sampleI == sampleCoords_.size() - 1)
00248         {
00249             //Info<< "calcSamples : Reached end of samples: "
00250             //    << "  sampleI now:" << sampleI
00251             //    << endl;
00252             break;
00253         }
00254 
00255         //
00256         // Segment sampleI .. sampleI+1 intersected by domain
00257         //
00258 
00259         // Initialize tracking starting from sampleI
00260         Cloud<passiveParticle> particles(mesh(), IDLList<passiveParticle>());
00261 
00262         passiveParticle singleParticle
00263         (
00264             particles,
00265             trackPt,
00266             trackCellI
00267         );
00268 
00269         bool bReached = trackToBoundary
00270         (
00271             singleParticle,
00272             sampleI,
00273             samplingPts,
00274             samplingCells,
00275             samplingFaces,
00276             samplingCurveDist
00277         );
00278 
00279         // fill sampleSegments
00280         for(label i = samplingPts.size() - 1; i >= startSegmentI; --i)
00281         {
00282             samplingSegments.append(segmentI);
00283         }
00284 
00285         if (!bReached)
00286         {
00287             //Info<< "calcSamples : Reached end of samples: "
00288             //    << "  sampleI now:" << sampleI
00289             //    << endl;
00290             break;
00291         }
00292         lastSample = singleParticle.position();
00293 
00294 
00295         // Find next boundary.
00296         sampleI++;
00297 
00298         if (sampleI == sampleCoords_.size() - 1)
00299         {
00300             //Info<< "calcSamples : Reached end of samples: "
00301             //    << "  sampleI now:" << sampleI
00302             //    << endl;
00303             break;
00304         }
00305 
00306         segmentI++;
00307 
00308         startSegmentI = samplingPts.size();
00309     }
00310 }
00311 
00312 
00313 void Foam::curveSet::genSamples()
00314 {
00315     // Storage for sample points
00316     DynamicList<point> samplingPts;
00317     DynamicList<label> samplingCells;
00318     DynamicList<label> samplingFaces;
00319     DynamicList<label> samplingSegments;
00320     DynamicList<scalar> samplingCurveDist;
00321 
00322     calcSamples
00323     (
00324         samplingPts,
00325         samplingCells,
00326         samplingFaces,
00327         samplingSegments,
00328         samplingCurveDist
00329     );
00330 
00331     samplingPts.shrink();
00332     samplingCells.shrink();
00333     samplingFaces.shrink();
00334     samplingSegments.shrink();
00335     samplingCurveDist.shrink();
00336 
00337     setSamples
00338     (
00339         samplingPts,
00340         samplingCells,
00341         samplingFaces,
00342         samplingSegments,
00343         samplingCurveDist
00344     );
00345 }
00346 
00347 
00348 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00349 
00350 Foam::curveSet::curveSet
00351 (
00352     const word& name,
00353     const polyMesh& mesh,
00354     meshSearch& searchEngine,
00355     const word& axis,
00356     const List<point>& sampleCoords
00357 )
00358 :
00359     sampledSet(name, mesh, searchEngine, axis),
00360     sampleCoords_(sampleCoords)
00361 {
00362     genSamples();
00363 
00364     if (debug)
00365     {
00366         write(Info);
00367     }
00368 }
00369 
00370 
00371 Foam::curveSet::curveSet
00372 (
00373     const word& name,
00374     const polyMesh& mesh,
00375     meshSearch& searchEngine,
00376     const dictionary& dict
00377 )
00378 :
00379     sampledSet(name, mesh, searchEngine, dict),
00380     sampleCoords_(dict.lookup("points"))
00381 {
00382     genSamples();
00383 
00384     if (debug)
00385     {
00386         write(Info);
00387     }
00388 }
00389 
00390 
00391 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00392 
00393 Foam::curveSet::~curveSet()
00394 {}
00395 
00396 
00397 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00398 
00399 Foam::point Foam::curveSet::getRefPoint(const List<point>& pts) const
00400 {
00401     if (pts.size())
00402     {
00403         // Use first samplePt as starting point
00404         return pts[0];
00405     }
00406     else
00407     {
00408         return vector::zero;
00409     }
00410 }
00411 
00412 
00413 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines