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

searchableSphere.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 "searchableSphere.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 
00029 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00030 
00031 namespace Foam
00032 {
00033 
00034 defineTypeNameAndDebug(searchableSphere, 0);
00035 addToRunTimeSelectionTable(searchableSurface, searchableSphere, dict);
00036 
00037 }
00038 
00039 
00040 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00041 
00042 Foam::pointIndexHit Foam::searchableSphere::findNearest
00043 (
00044     const point& sample,
00045     const scalar nearestDistSqr
00046 ) const
00047 {
00048     pointIndexHit info(false, sample, -1);
00049 
00050     const vector n(sample-centre_);
00051     scalar magN = mag(n);
00052 
00053     if (nearestDistSqr > sqr(magN-radius_))
00054     {
00055         if (magN < ROOTVSMALL)
00056         {
00057             info.rawPoint() = centre_ + vector(1,0,0)/magN*radius_;
00058         }
00059         else
00060         {
00061             info.rawPoint() = centre_ + n/magN*radius_;
00062         }
00063         info.setHit();
00064         info.setIndex(0);
00065     }
00066 
00067     return info;
00068 }
00069 
00070 
00071 // From Graphics Gems - intersection of sphere with ray
00072 void Foam::searchableSphere::findLineAll
00073 (
00074     const point& start,
00075     const point& end,
00076     pointIndexHit& near,
00077     pointIndexHit& far
00078 ) const
00079 {
00080     near.setMiss();
00081     far.setMiss();
00082 
00083     vector dir(end-start);
00084     scalar magSqrDir = magSqr(dir);
00085 
00086     if (magSqrDir > ROOTVSMALL)
00087     {
00088         const vector toCentre(centre_-start);
00089         scalar magSqrToCentre = magSqr(toCentre);
00090 
00091         dir /= Foam::sqrt(magSqrDir);
00092 
00093         scalar v = (toCentre & dir);
00094 
00095         scalar disc = sqr(radius_) - (magSqrToCentre - sqr(v));
00096 
00097         if (disc >= 0)
00098         {
00099             scalar d = Foam::sqrt(disc);
00100 
00101             scalar nearParam = v-d;
00102 
00103             if (nearParam >= 0 && sqr(nearParam) <= magSqrDir)
00104             {
00105                 near.setHit();
00106                 near.setPoint(start + nearParam*dir);
00107                 near.setIndex(0);
00108             }
00109 
00110             scalar farParam = v+d;
00111 
00112             if (farParam >= 0 && sqr(farParam) <= magSqrDir)
00113             {
00114                 far.setHit();
00115                 far.setPoint(start + farParam*dir);
00116                 far.setIndex(0);
00117             }
00118         }
00119     }
00120 }
00121 
00122 
00123 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00124 
00125 Foam::searchableSphere::searchableSphere
00126 (
00127     const IOobject& io,
00128     const point& centre,
00129     const scalar radius
00130 )
00131 :
00132     searchableSurface(io),
00133     centre_(centre),
00134     radius_(radius)
00135 {}
00136 
00137 
00138 Foam::searchableSphere::searchableSphere
00139 (
00140     const IOobject& io,
00141     const dictionary& dict
00142 )
00143 :
00144     searchableSurface(io),
00145     centre_(dict.lookup("centre")),
00146     radius_(readScalar(dict.lookup("radius")))
00147 {}
00148 
00149 
00150 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00151 
00152 Foam::searchableSphere::~searchableSphere()
00153 {}
00154 
00155 
00156 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00157 
00158 const Foam::wordList& Foam::searchableSphere::regions() const
00159 {
00160     if (regions_.empty())
00161     {
00162         regions_.setSize(1);
00163         regions_[0] = "region0";
00164     }
00165     return regions_;
00166 }
00167 
00168 
00169 
00170 void Foam::searchableSphere::findNearest
00171 (
00172     const pointField& samples,
00173     const scalarField& nearestDistSqr,
00174     List<pointIndexHit>& info
00175 ) const
00176 {
00177     info.setSize(samples.size());
00178 
00179     forAll(samples, i)
00180     {
00181         info[i] = findNearest(samples[i], nearestDistSqr[i]);
00182     }
00183 }
00184 
00185 
00186 void Foam::searchableSphere::findLine
00187 (
00188     const pointField& start,
00189     const pointField& end,
00190     List<pointIndexHit>& info
00191 ) const
00192 {
00193     info.setSize(start.size());
00194 
00195     pointIndexHit b;
00196 
00197     forAll(start, i)
00198     {
00199         // Pick nearest intersection. If none intersected take second one.
00200         findLineAll(start[i], end[i], info[i], b);
00201         if (!info[i].hit() && b.hit())
00202         {
00203             info[i] = b;
00204         }
00205     }
00206 }
00207 
00208 
00209 void Foam::searchableSphere::findLineAny
00210 (
00211     const pointField& start,
00212     const pointField& end,
00213     List<pointIndexHit>& info
00214 ) const
00215 {
00216     info.setSize(start.size());
00217 
00218     pointIndexHit b;
00219 
00220     forAll(start, i)
00221     {
00222         // Discard far intersection
00223         findLineAll(start[i], end[i], info[i], b);
00224         if (!info[i].hit() && b.hit())
00225         {
00226             info[i] = b;
00227         }
00228     }
00229 }
00230 
00231 
00232 void Foam::searchableSphere::findLineAll
00233 (
00234     const pointField& start,
00235     const pointField& end,
00236     List<List<pointIndexHit> >& info
00237 ) const
00238 {
00239     info.setSize(start.size());
00240 
00241     forAll(start, i)
00242     {
00243         pointIndexHit near, far;
00244         findLineAll(start[i], end[i], near, far);
00245 
00246         if (near.hit())
00247         {
00248             if (far.hit())
00249             {
00250                 info[i].setSize(2);
00251                 info[i][0] = near;
00252                 info[i][1] = far;
00253             }
00254             else
00255             {
00256                 info[i].setSize(1);
00257                 info[i][0] = near;
00258             }
00259         }
00260         else
00261         {
00262             if (far.hit())
00263             {
00264                 info[i].setSize(1);
00265                 info[i][0] = far;
00266             }
00267             else
00268             {
00269                 info[i].clear();
00270             }
00271         }
00272     }
00273 }
00274 
00275 
00276 void Foam::searchableSphere::getRegion
00277 (
00278     const List<pointIndexHit>& info,
00279     labelList& region
00280 ) const
00281 {
00282     region.setSize(info.size());
00283     region = 0;
00284 }
00285 
00286 
00287 void Foam::searchableSphere::getNormal
00288 (
00289     const List<pointIndexHit>& info,
00290     vectorField& normal
00291 ) const
00292 {
00293     normal.setSize(info.size());
00294     normal = vector::zero;
00295 
00296     forAll(info, i)
00297     {
00298         if (info[i].hit())
00299         {
00300             normal[i] = info[i].hitPoint() - centre_;
00301 
00302             normal[i] /= mag(normal[i])+VSMALL;
00303         }
00304         else
00305         {
00306             // Set to what?
00307         }
00308     }
00309 }
00310 
00311 
00312 void Foam::searchableSphere::getVolumeType
00313 (
00314     const pointField& points,
00315     List<volumeType>& volType
00316 ) const
00317 {
00318     volType.setSize(points.size());
00319     volType = INSIDE;
00320 
00321     forAll(points, pointI)
00322     {
00323         const point& pt = points[pointI];
00324 
00325         if (magSqr(pt - centre_) <= sqr(radius_))
00326         {
00327             volType[pointI] = INSIDE;
00328         }
00329         else
00330         {
00331             volType[pointI] = OUTSIDE;
00332         }
00333     }
00334 }
00335 
00336 
00337 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines