1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "searchableSphere.H"
27 #include "addToRunTimeSelectionTable.H"
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 defineTypeNameAndDebug(searchableSphere, 0);
35 addToRunTimeSelectionTable(searchableSurface, searchableSphere, dict);
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 Foam::pointIndexHit Foam::searchableSphere::findNearest
45 const scalar nearestDistSqr
48 pointIndexHit info(false, sample, -1);
50 const vector n(sample-centre_);
53 if (nearestDistSqr > sqr(magN-radius_))
55 if (magN < ROOTVSMALL)
57 info.rawPoint() = centre_ + vector(1,0,0)/magN*radius_;
61 info.rawPoint() = centre_ + n/magN*radius_;
71 // From Graphics Gems - intersection of sphere with ray
72 void Foam::searchableSphere::findLineAll
83 vector dir(end-start);
84 scalar magSqrDir = magSqr(dir);
86 if (magSqrDir > ROOTVSMALL)
88 const vector toCentre(centre_-start);
89 scalar magSqrToCentre = magSqr(toCentre);
91 dir /= Foam::sqrt(magSqrDir);
93 scalar v = (toCentre & dir);
95 scalar disc = sqr(radius_) - (magSqrToCentre - sqr(v));
99 scalar d = Foam::sqrt(disc);
101 scalar nearParam = v-d;
103 if (nearParam >= 0 && sqr(nearParam) <= magSqrDir)
106 near.setPoint(start + nearParam*dir);
110 scalar farParam = v+d;
112 if (farParam >= 0 && sqr(farParam) <= magSqrDir)
115 far.setPoint(start + farParam*dir);
123 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
125 Foam::searchableSphere::searchableSphere
132 searchableSurface(io),
138 Foam::searchableSphere::searchableSphere
141 const dictionary& dict
144 searchableSurface(io),
145 centre_(dict.lookup("centre")),
146 radius_(readScalar(dict.lookup("radius")))
150 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
152 Foam::searchableSphere::~searchableSphere()
156 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
158 const Foam::wordList& Foam::searchableSphere::regions() const
160 if (regions_.empty())
163 regions_[0] = "region0";
170 void Foam::searchableSphere::findNearest
172 const pointField& samples,
173 const scalarField& nearestDistSqr,
174 List<pointIndexHit>& info
177 info.setSize(samples.size());
181 info[i] = findNearest(samples[i], nearestDistSqr[i]);
186 void Foam::searchableSphere::findLine
188 const pointField& start,
189 const pointField& end,
190 List<pointIndexHit>& info
193 info.setSize(start.size());
199 // Pick nearest intersection. If none intersected take second one.
200 findLineAll(start[i], end[i], info[i], b);
201 if (!info[i].hit() && b.hit())
209 void Foam::searchableSphere::findLineAny
211 const pointField& start,
212 const pointField& end,
213 List<pointIndexHit>& info
216 info.setSize(start.size());
222 // Discard far intersection
223 findLineAll(start[i], end[i], info[i], b);
224 if (!info[i].hit() && b.hit())
232 void Foam::searchableSphere::findLineAll
234 const pointField& start,
235 const pointField& end,
236 List<List<pointIndexHit> >& info
239 info.setSize(start.size());
243 pointIndexHit near, far;
244 findLineAll(start[i], end[i], near, far);
276 void Foam::searchableSphere::getRegion
278 const List<pointIndexHit>& info,
282 region.setSize(info.size());
287 void Foam::searchableSphere::getNormal
289 const List<pointIndexHit>& info,
293 normal.setSize(info.size());
294 normal = vector::zero;
300 normal[i] = info[i].hitPoint() - centre_;
302 normal[i] /= mag(normal[i])+VSMALL;
312 void Foam::searchableSphere::getVolumeType
314 const pointField& points,
315 List<volumeType>& volType
318 volType.setSize(points.size());
321 forAll(points, pointI)
323 const point& pt = points[pointI];
325 if (magSqr(pt - centre_) <= sqr(radius_))
327 volType[pointI] = INSIDE;
331 volType[pointI] = OUTSIDE;
337 // ************************************************************************* //