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

searchablePlate.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 "searchablePlate.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <OpenFOAM/SortableList.H>
00029 
00030 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00031 
00032 namespace Foam
00033 {
00034 
00035 defineTypeNameAndDebug(searchablePlate, 0);
00036 addToRunTimeSelectionTable(searchableSurface, searchablePlate, dict);
00037 
00038 }
00039 
00040 
00041 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00042 
00043 Foam::direction Foam::searchablePlate::calcNormal(const point& span)
00044 {
00045     direction normalDir = 3;
00046 
00047     for (direction dir = 0; dir < vector::nComponents; dir++)
00048     {
00049         if (span[dir] < 0)
00050         {
00051             FatalErrorIn("searchablePlate::calcNormal()")
00052                 << "Span should have two positive and one zero entry. Now:"
00053                 << span << exit(FatalError);
00054         }
00055         else if (span[dir] < VSMALL)
00056         {
00057             if (normalDir == 3)
00058             {
00059                 normalDir = dir;
00060             }
00061             else
00062             {
00063                 // Multiple zero entries. Flag and exit.
00064                 normalDir = 3;
00065                 break;
00066             }
00067         }
00068     }
00069 
00070     if (normalDir == 3)
00071     {
00072         FatalErrorIn("searchablePlate::calcNormal()")
00073             << "Span should have one and only zero entry. Now:" << span
00074             << exit(FatalError);
00075     }
00076 
00077     return normalDir;
00078 }
00079 
00080 
00081 // Returns miss or hit with face (always 0)
00082 Foam::pointIndexHit Foam::searchablePlate::findNearest
00083 (
00084     const point& sample,
00085     const scalar nearestDistSqr
00086 ) const
00087 {
00088     // For every component direction can be
00089     // left of min, right of max or inbetween.
00090     // - outside points: project first one x plane (either min().x()
00091     // or max().x()), then onto y plane and finally z. You should be left
00092     // with intersection point
00093     // - inside point: find nearest side (compare to mid point). Project onto
00094     //   that.
00095 
00096     // Project point on plane.
00097     pointIndexHit info(true, sample, 0);
00098     info.rawPoint()[normalDir_] = origin_[normalDir_];
00099 
00100     // Clip to edges if outside
00101     for (direction dir = 0; dir < vector::nComponents; dir++)
00102     {
00103         if (dir != normalDir_)
00104         {
00105             if (info.rawPoint()[dir] < origin_[dir])
00106             {
00107                 info.rawPoint()[dir] = origin_[dir];
00108             }
00109             else if (info.rawPoint()[dir] > origin_[dir]+span_[dir])
00110             {
00111                 info.rawPoint()[dir] = origin_[dir]+span_[dir];
00112             }
00113         }
00114     }
00115 
00116     // Check if outside. Optimisation: could do some checks on distance already
00117     // on components above
00118     if (magSqr(info.rawPoint() - sample) > nearestDistSqr)
00119     {
00120         info.setMiss();
00121         info.setIndex(-1);
00122     }
00123 
00124     return info;
00125 }
00126 
00127 
00128 Foam::pointIndexHit Foam::searchablePlate::findLine
00129 (
00130     const point& start,
00131     const point& end
00132 ) const
00133 {
00134     pointIndexHit info
00135     (
00136         true,
00137         vector::zero,
00138         0
00139     );
00140 
00141     const vector dir(end-start);
00142 
00143     if (mag(dir[normalDir_]) < VSMALL)
00144     {
00145         info.setMiss();
00146         info.setIndex(-1);
00147     }
00148     else
00149     {
00150         scalar t = (origin_[normalDir_]-start[normalDir_]) / dir[normalDir_];
00151 
00152         if (t < 0 || t > 1)
00153         {
00154             info.setMiss();
00155             info.setIndex(-1);
00156         }
00157         else
00158         {
00159             info.rawPoint() = start+t*dir;
00160             info.rawPoint()[normalDir_] = origin_[normalDir_];
00161 
00162             // Clip to edges
00163             for (direction dir = 0; dir < vector::nComponents; dir++)
00164             {
00165                 if (dir != normalDir_)
00166                 {
00167                     if (info.rawPoint()[dir] < origin_[dir])
00168                     {
00169                         info.setMiss();
00170                         info.setIndex(-1);
00171                         break;
00172                     }
00173                     else if (info.rawPoint()[dir] > origin_[dir]+span_[dir])
00174                     {
00175                         info.setMiss();
00176                         info.setIndex(-1);
00177                         break;
00178                     }
00179                 }
00180             }
00181         }
00182     }
00183 
00184     // Debug
00185     if (info.hit())
00186     {
00187         treeBoundBox bb(origin_, origin_+span_);
00188         bb.min()[normalDir_] -= 1E-6;
00189         bb.max()[normalDir_] += 1E-6;
00190 
00191         if (!bb.contains(info.hitPoint()))
00192         {
00193             FatalErrorIn("searchablePlate::findLine(..)")
00194                 << "bb:" << bb << endl
00195                 << "origin_:" << origin_ << endl
00196                 << "span_:" << span_ << endl
00197                 << "normalDir_:" << normalDir_ << endl
00198                 << "hitPoint:" << info.hitPoint()
00199                 << abort(FatalError);
00200         }
00201     }
00202 
00203     return info;
00204 }
00205 
00206 
00207 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00208 
00209 Foam::searchablePlate::searchablePlate
00210 (
00211     const IOobject& io,
00212     const point& origin,
00213     const vector& span
00214 )
00215 :
00216     searchableSurface(io),
00217     origin_(origin),
00218     span_(span),
00219     normalDir_(calcNormal(span_))
00220 {
00221     if (debug)
00222     {
00223         Info<< "searchablePlate::searchablePlate :"
00224             << " origin:" << origin_
00225             << " origin+span:" << origin_+span_
00226             << " normal:" << vector::componentNames[normalDir_]
00227             << endl;
00228     }
00229 }
00230 
00231 
00232 Foam::searchablePlate::searchablePlate
00233 (
00234     const IOobject& io,
00235     const dictionary& dict
00236 )
00237 :
00238     searchableSurface(io),
00239     origin_(dict.lookup("origin")),
00240     span_(dict.lookup("span")),
00241     normalDir_(calcNormal(span_))
00242 {
00243     if (debug)
00244     {
00245         Info<< "searchablePlate::searchablePlate :"
00246             << " origin:" << origin_
00247             << " origin+span:" << origin_+span_
00248             << " normal:" << vector::componentNames[normalDir_]
00249             << endl;
00250     }
00251 }
00252 
00253 
00254 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00255 
00256 Foam::searchablePlate::~searchablePlate()
00257 {}
00258 
00259 
00260 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00261 
00262 const Foam::wordList& Foam::searchablePlate::regions() const
00263 {
00264     if (regions_.empty())
00265     {
00266         regions_.setSize(1);
00267         regions_[0] = "region0";
00268     }
00269     return regions_;
00270 }
00271 
00272 
00273 void Foam::searchablePlate::findNearest
00274 (
00275     const pointField& samples,
00276     const scalarField& nearestDistSqr,
00277     List<pointIndexHit>& info
00278 ) const
00279 {
00280     info.setSize(samples.size());
00281 
00282     forAll(samples, i)
00283     {
00284         info[i] = findNearest(samples[i], nearestDistSqr[i]);
00285     }
00286 }
00287 
00288 
00289 void Foam::searchablePlate::findLine
00290 (
00291     const pointField& start,
00292     const pointField& end,
00293     List<pointIndexHit>& info
00294 ) const
00295 {
00296     info.setSize(start.size());
00297 
00298     forAll(start, i)
00299     {
00300         info[i] = findLine(start[i], end[i]);
00301     }
00302 }
00303 
00304 
00305 void Foam::searchablePlate::findLineAny
00306 (
00307     const pointField& start,
00308     const pointField& end,
00309     List<pointIndexHit>& info
00310 ) const
00311 {
00312     findLine(start, end, info);
00313 }
00314 
00315 
00316 void Foam::searchablePlate::findLineAll
00317 (
00318     const pointField& start,
00319     const pointField& end,
00320     List<List<pointIndexHit> >& info
00321 ) const
00322 {
00323     List<pointIndexHit> nearestInfo;
00324     findLine(start, end, nearestInfo);
00325 
00326     info.setSize(start.size());
00327     forAll(info, pointI)
00328     {
00329         if (nearestInfo[pointI].hit())
00330         {
00331             info[pointI].setSize(1);
00332             info[pointI][0] = nearestInfo[pointI];
00333         }
00334         else
00335         {
00336             info[pointI].clear();
00337         }
00338     }
00339 }
00340 
00341 
00342 void Foam::searchablePlate::getRegion
00343 (
00344     const List<pointIndexHit>& info,
00345     labelList& region
00346 ) const
00347 {
00348     region.setSize(info.size());
00349     region = 0;
00350 }
00351 
00352 
00353 void Foam::searchablePlate::getNormal
00354 (
00355     const List<pointIndexHit>& info,
00356     vectorField& normal
00357 ) const
00358 {
00359     normal.setSize(info.size());
00360     normal = vector::zero;
00361     forAll(normal, i)
00362     {
00363         normal[i][normalDir_] = 1.0;
00364     }
00365 }
00366 
00367 
00368 void Foam::searchablePlate::getVolumeType
00369 (
00370     const pointField& points,
00371     List<volumeType>& volType
00372 ) const
00373 {
00374     FatalErrorIn
00375     (
00376         "searchableCollection::getVolumeType(const pointField&"
00377         ", List<volumeType>&) const"
00378     )   << "Volume type not supported for plate."
00379         << exit(FatalError);
00380 }
00381 
00382 
00383 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines