1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "searchableSphere.H"
28 #include "addToRunTimeSelectionTable.H"
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 defineTypeNameAndDebug(searchableSphere, 0);
36 addToRunTimeSelectionTable(searchableSurface, searchableSphere, dict);
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 Foam::pointIndexHit Foam::searchableSphere::findNearest
46 const scalar nearestDistSqr
49 pointIndexHit info(false, sample, -1);
51 const vector n(sample-centre_);
54 if (nearestDistSqr > sqr(magN-radius_))
56 if (magN < ROOTVSMALL)
58 info.rawPoint() = centre_ + vector(1,0,0)/magN*radius_;
62 info.rawPoint() = centre_ + n/magN*radius_;
72 // From Graphics Gems - intersection of sphere with ray
73 void Foam::searchableSphere::findLineAll
84 vector dir(end-start);
85 scalar magSqrDir = magSqr(dir);
87 if (magSqrDir > ROOTVSMALL)
89 const vector toCentre(centre_-start);
90 scalar magSqrToCentre = magSqr(toCentre);
92 dir /= Foam::sqrt(magSqrDir);
94 scalar v = (toCentre & dir);
96 scalar disc = sqr(radius_) - (magSqrToCentre - sqr(v));
100 scalar d = Foam::sqrt(disc);
102 scalar nearParam = v-d;
104 if (nearParam >= 0 && sqr(nearParam) <= magSqrDir)
107 near.setPoint(start + nearParam*dir);
111 scalar farParam = v+d;
113 if (farParam >= 0 && sqr(farParam) <= magSqrDir)
116 far.setPoint(start + farParam*dir);
124 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
126 Foam::searchableSphere::searchableSphere
133 searchableSurface(io),
139 Foam::searchableSphere::searchableSphere
142 const dictionary& dict
145 searchableSurface(io),
146 centre_(dict.lookup("centre")),
147 radius_(readScalar(dict.lookup("radius")))
151 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
153 Foam::searchableSphere::~searchableSphere()
157 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
159 const Foam::wordList& Foam::searchableSphere::regions() const
161 if (regions_.empty())
164 regions_[0] = "region0";
171 void Foam::searchableSphere::findNearest
173 const pointField& samples,
174 const scalarField& nearestDistSqr,
175 List<pointIndexHit>& info
178 info.setSize(samples.size());
182 info[i] = findNearest(samples[i], nearestDistSqr[i]);
187 void Foam::searchableSphere::findLine
189 const pointField& start,
190 const pointField& end,
191 List<pointIndexHit>& info
194 info.setSize(start.size());
200 // Pick nearest intersection. If none intersected take second one.
201 findLineAll(start[i], end[i], info[i], b);
202 if (!info[i].hit() && b.hit())
210 void Foam::searchableSphere::findLineAny
212 const pointField& start,
213 const pointField& end,
214 List<pointIndexHit>& info
217 info.setSize(start.size());
223 // Discard far intersection
224 findLineAll(start[i], end[i], info[i], b);
225 if (!info[i].hit() && b.hit())
233 void Foam::searchableSphere::findLineAll
235 const pointField& start,
236 const pointField& end,
237 List<List<pointIndexHit> >& info
240 info.setSize(start.size());
244 pointIndexHit near, far;
245 findLineAll(start[i], end[i], near, far);
277 void Foam::searchableSphere::getRegion
279 const List<pointIndexHit>& info,
283 region.setSize(info.size());
288 void Foam::searchableSphere::getNormal
290 const List<pointIndexHit>& info,
294 normal.setSize(info.size());
295 normal = vector::zero;
301 normal[i] = info[i].hitPoint() - centre_;
303 normal[i] /= mag(normal[i])+VSMALL;
313 void Foam::searchableSphere::getVolumeType
315 const pointField& points,
316 List<volumeType>& volType
319 volType.setSize(points.size());
322 forAll(points, pointI)
324 const point& pt = points[pointI];
326 if (magSqr(pt - centre_) <= sqr(radius_))
328 volType[pointI] = INSIDE;
332 volType[pointI] = OUTSIDE;
338 // ************************************************************************* //