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

sampledSet.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 "sampledSet.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <OpenFOAM/primitiveMesh.H>
00029 #include <meshTools/meshSearch.H>
00030 #include <sampling/writer.H>
00031 
00032 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00033 
00034 namespace Foam
00035 {
00036     const scalar sampledSet::tol = 1e-6;
00037 
00038     defineTypeNameAndDebug(sampledSet, 0);
00039     defineRunTimeSelectionTable(sampledSet, word);
00040 }
00041 
00042 
00043 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00044 
00045 Foam::label Foam::sampledSet::getBoundaryCell(const label faceI) const
00046 {
00047     return mesh().faceOwner()[faceI];
00048 }
00049 
00050 
00051 Foam::label Foam::sampledSet::getCell
00052 (
00053     const label faceI,
00054     const point& sample
00055 ) const
00056 {
00057     if (faceI == -1)
00058     {
00059         FatalErrorIn
00060         (
00061             "sampledSet::getCell(const label, const point&)"
00062         )   << "Illegal face label " << faceI
00063             << abort(FatalError);
00064     }
00065 
00066     if (faceI >= mesh().nInternalFaces())
00067     {
00068         label cellI = getBoundaryCell(faceI);
00069 
00070         if (!mesh().pointInCell(sample, cellI))
00071         {
00072             FatalErrorIn
00073             (
00074                 "sampledSet::getCell(const label, const point&)"
00075             )   << "Found cell " << cellI << " using face " << faceI
00076                 << ". But cell does not contain point " << sample
00077                 << abort(FatalError);
00078         }
00079         return cellI;
00080     }
00081     else
00082     {
00083         // Try owner and neighbour to see which one contains sample
00084 
00085         label cellI = mesh().faceOwner()[faceI];
00086 
00087         if (mesh().pointInCell(sample, cellI))
00088         {
00089             return cellI;
00090         }
00091         else
00092         {
00093             cellI = mesh().faceNeighbour()[faceI];
00094 
00095             if (mesh().pointInCell(sample, cellI))
00096             {
00097                 return cellI;
00098             }
00099             else
00100             {
00101                 FatalErrorIn
00102                 (
00103                     "sampledSet::getCell(const label, const point&)"
00104                 )   << "None of the neighbours of face "
00105                     << faceI << " contains point " << sample
00106                     << abort(FatalError);
00107 
00108                 return -1;
00109             }
00110         }
00111     }
00112 }
00113 
00114 
00115 Foam::scalar Foam::sampledSet::calcSign
00116 (
00117     const label faceI,
00118     const point& sample
00119 ) const
00120 {
00121     vector vec = sample - mesh().faceCentres()[faceI];
00122 
00123     scalar magVec = mag(vec);
00124 
00125     if (magVec < VSMALL)
00126     {
00127         // sample on face centre. Regard as inside
00128         return -1;
00129     }
00130 
00131     vec /= magVec;
00132 
00133     vector n = mesh().faceAreas()[faceI];
00134 
00135     n /= mag(n) + VSMALL;
00136 
00137     return n & vec;
00138 }
00139 
00140 
00141 // Return face (or -1) of face which is within smallDist of sample
00142 Foam::label Foam::sampledSet::findNearFace
00143 (
00144     const label cellI,
00145     const point& sample,
00146     const scalar smallDist
00147 ) const
00148 {
00149     const cell& myFaces = mesh().cells()[cellI];
00150 
00151     forAll(myFaces, myFaceI)
00152     {
00153         const face& f = mesh().faces()[myFaces[myFaceI]];
00154 
00155         pointHit inter = f.nearestPoint(sample, mesh().points());
00156 
00157         scalar dist;
00158 
00159         if (inter.hit())
00160         {
00161             dist = mag(inter.hitPoint() - sample);
00162         }
00163         else
00164         {
00165             dist = mag(inter.missPoint() - sample);
00166         }
00167 
00168         if (dist < smallDist)
00169         {
00170             return myFaces[myFaceI];
00171         }
00172     }
00173     return -1;
00174 }
00175 
00176 
00177 // 'Pushes' point facePt (which is almost on face) in direction of cell centre
00178 // so it is clearly inside.
00179 Foam::point Foam::sampledSet::pushIn
00180 (
00181     const point& facePt,
00182     const label faceI
00183 ) const
00184 {
00185     label cellI = mesh().faceOwner()[faceI];
00186 
00187     const point& cellCtr = mesh().cellCentres()[cellI];
00188 
00189     point newSample =
00190         facePt + tol*(cellCtr - facePt);
00191 
00192     if (!searchEngine().pointInCell(newSample, cellI))
00193     {
00194         FatalErrorIn
00195         (
00196             "sampledSet::pushIn(const point&, const label)"
00197         )   << "After pushing " << facePt << " to " << newSample
00198             << " it is still outside faceI " << faceI << endl
00199             << "Please change your starting point"
00200             << abort(FatalError);
00201     }
00202     //Info<< "pushIn : moved " << facePt << " to " << newSample
00203     //    << endl;
00204 
00205     return newSample;
00206 }
00207 
00208 
00209 // Calculates start of tracking given samplePt and first boundary intersection
00210 // (bPoint, bFaceI). bFaceI == -1 if no boundary intersection.
00211 // Returns true if trackPt is sampling point
00212 bool Foam::sampledSet::getTrackingPoint
00213 (
00214     const vector& offset,
00215     const point& samplePt,
00216     const point& bPoint,
00217     const label bFaceI,
00218 
00219     point& trackPt,
00220     label& trackCellI,
00221     label& trackFaceI
00222 ) const
00223 {
00224     const scalar smallDist = mag(tol*offset);
00225 
00226     bool isGoodSample = false;
00227 
00228     if (bFaceI == -1)
00229     {
00230         // No boundary intersection. Try and find cell samplePt is in
00231         trackCellI = mesh().findCell(samplePt);
00232 
00233         if
00234         (
00235             (trackCellI == -1)
00236          || !mesh().pointInCell(samplePt, trackCellI)
00237         )
00238         {
00239             // Line samplePt - end_ does not intersect domain at all.
00240             // (or is along edge)
00241             //Info<< "getTrackingPoint : samplePt outside domain : "
00242             //    << "  samplePt:" << samplePt
00243             //    << endl;
00244 
00245             trackCellI = -1;
00246             trackFaceI = -1;
00247 
00248             isGoodSample = false;
00249         }
00250         else
00251         {
00252             // start is inside. Use it as tracking point
00253             //Info<< "getTrackingPoint : samplePt inside :"
00254             //    << "  samplePt:" << samplePt
00255             //    << "  trackCellI:" << trackCellI
00256             //    << endl;
00257 
00258             trackPt = samplePt;
00259             trackFaceI = -1;
00260 
00261             isGoodSample = true;
00262         }
00263     }
00264     else if (mag(samplePt - bPoint) < smallDist)
00265     {
00266         //Info<< "getTrackingPoint : samplePt:" << samplePt
00267         //    << " close to bPoint:"
00268         //    << bPoint << endl;
00269 
00270         // samplePt close to bPoint. Snap to it
00271         trackPt = pushIn(bPoint, bFaceI);
00272         trackFaceI = bFaceI;
00273         trackCellI = getBoundaryCell(trackFaceI);
00274 
00275         isGoodSample = true;
00276     }
00277     else
00278     {
00279         scalar sign = calcSign(bFaceI, samplePt);
00280 
00281         if (sign < 0)
00282         {
00283             // samplePt inside or marginally outside.
00284             trackPt = samplePt;
00285             trackFaceI = -1;
00286             trackCellI = mesh().findCell(trackPt);
00287 
00288             isGoodSample = true;
00289         }
00290         else
00291         {
00292             // samplePt outside. use bPoint
00293             trackPt = pushIn(bPoint, bFaceI);
00294             trackFaceI = bFaceI;
00295             trackCellI = getBoundaryCell(trackFaceI);
00296 
00297             isGoodSample = false;
00298         }
00299     }
00300 
00301     if (debug)
00302     {
00303         Info<< "sampledSet::getTrackingPoint :"
00304             << " offset:" << offset
00305             << " samplePt:" << samplePt
00306             << " bPoint:" << bPoint
00307             << " bFaceI:" << bFaceI
00308             << endl << "   Calculated first tracking point :"
00309             << " trackPt:" << trackPt
00310             << " trackCellI:" << trackCellI
00311             << " trackFaceI:" << trackFaceI
00312             << " isGoodSample:" << isGoodSample
00313             << endl;
00314     }
00315 
00316     return isGoodSample;
00317 }
00318 
00319 
00320 void Foam::sampledSet::setSamples
00321 (
00322     const List<point>& samplingPts,
00323     const labelList& samplingCells,
00324     const labelList& samplingFaces,
00325     const labelList& samplingSegments,
00326     const scalarList& samplingCurveDist
00327 )
00328 {
00329     setSize(samplingPts.size());
00330     cells_.setSize(samplingCells.size());
00331     faces_.setSize(samplingFaces.size());
00332     segments_.setSize(samplingSegments.size());
00333     curveDist_.setSize(samplingCurveDist.size());
00334 
00335     if
00336     (
00337         (cells_.size() != size())
00338      || (faces_.size() != size())
00339      || (segments_.size() != size())
00340      || (curveDist_.size() != size())
00341     )
00342     {
00343         FatalErrorIn("sampledSet::setSamples()")
00344             << "sizes not equal : "
00345             << "  points:" << size()
00346             << "  cells:" << cells_.size()
00347             << "  faces:" << faces_.size()
00348             << "  segments:" << segments_.size()
00349             << "  curveDist:" << curveDist_.size()
00350             << abort(FatalError);
00351     }
00352 
00353     forAll(samplingPts, sampleI)
00354     {
00355         operator[](sampleI) = samplingPts[sampleI];
00356     }
00357     cells_ = samplingCells;
00358     faces_ = samplingFaces;
00359     segments_ = samplingSegments;
00360     curveDist_ = samplingCurveDist;
00361 }
00362 
00363 
00364 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00365 
00366 Foam::sampledSet::sampledSet
00367 (
00368     const word& name,
00369     const polyMesh& mesh,
00370     meshSearch& searchEngine,
00371     const word& axis
00372 )
00373 :
00374     coordSet(name, axis),
00375     mesh_(mesh),
00376     searchEngine_(searchEngine),
00377     segments_(0),
00378     curveDist_(0),
00379     cells_(0),
00380     faces_(0)
00381 {}
00382 
00383 
00384 Foam::sampledSet::sampledSet
00385 (
00386     const word& name,
00387     const polyMesh& mesh,
00388     meshSearch& searchEngine,
00389     const dictionary& dict
00390 )
00391 :
00392     coordSet(name, dict.lookup("axis")),
00393     mesh_(mesh),
00394     searchEngine_(searchEngine),
00395     segments_(0),
00396     curveDist_(0),
00397     cells_(0),
00398     faces_(0)
00399 {}
00400 
00401 
00402 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00403 
00404 Foam::sampledSet::~sampledSet()
00405 {}
00406 
00407 
00408 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00409 
00410 Foam::autoPtr<Foam::sampledSet> Foam::sampledSet::New
00411 (
00412     const word& name,
00413     const polyMesh& mesh,
00414     meshSearch& searchEngine,
00415     const dictionary& dict
00416 )
00417 {
00418     word sampleType(dict.lookup("type"));
00419 
00420     wordConstructorTable::iterator cstrIter =
00421         wordConstructorTablePtr_->find(sampleType);
00422 
00423     if (cstrIter == wordConstructorTablePtr_->end())
00424     {
00425         FatalErrorIn
00426         (
00427             "sampledSet::New(const word&, "
00428             "const polyMesh&, meshSearch&, const dictionary&)"
00429         )   << "Unknown sample type " << sampleType
00430             << nl << nl
00431             << "Valid sample types : " << nl
00432             << wordConstructorTablePtr_->sortedToc()
00433             << exit(FatalError);
00434     }
00435 
00436     return autoPtr<sampledSet>
00437     (
00438         cstrIter()
00439         (
00440             name,
00441             mesh,
00442             searchEngine,
00443             dict
00444         )
00445     );
00446 }
00447 
00448 
00449 Foam::Ostream& Foam::sampledSet::write(Ostream& os) const
00450 {
00451     coordSet::write(os);
00452 
00453     os  << endl << "\t(cellI)\t(faceI)" << endl;
00454 
00455     forAll(*this, sampleI)
00456     {
00457         os  << '\t' << cells_[sampleI]
00458             << '\t' << faces_[sampleI]
00459             << endl;
00460     }
00461 
00462     return os;
00463 }
00464 
00465 
00466 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines