sphere_searchableSurface.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  namespace searchableSurfaces
34  {
36 
38  (
40  sphere,
42  );
43 
45  (
47  sphere,
48  dictionary,
49  searchableSphere,
50  "searchableSphere"
51  );
52  }
53 }
54 
55 
56 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
57 
58 Foam::pointIndexHit Foam::searchableSurfaces::sphere::findNearest
59 (
60  const point& sample,
61  const scalar nearestDistSqr
62 ) const
63 {
64  pointIndexHit info(false, sample, -1);
65 
66  const vector n(sample - centre_);
67  scalar magN = mag(n);
68 
69  if (nearestDistSqr >= sqr(magN - radius_))
70  {
71  if (magN < rootVSmall)
72  {
73  info.rawPoint() = centre_ + vector(1,0,0)*radius_;
74  }
75  else
76  {
77  info.rawPoint() = centre_ + n/magN*radius_;
78  }
79  info.setHit();
80  info.setIndex(0);
81  }
82 
83  return info;
84 }
85 
86 
87 // From Graphics Gems - intersection of sphere with ray
88 void Foam::searchableSurfaces::sphere::findLineAll
89 (
90  const point& start,
91  const point& end,
92  pointIndexHit& near,
93  pointIndexHit& far
94 ) const
95 {
96  near.setMiss();
97  far.setMiss();
98 
99  vector dir(end-start);
100  scalar magSqrDir = magSqr(dir);
101 
102  if (magSqrDir > rootVSmall)
103  {
104  const vector toCentre(centre_-start);
105  scalar magSqrToCentre = magSqr(toCentre);
106 
107  dir /= Foam::sqrt(magSqrDir);
108 
109  scalar v = (toCentre & dir);
110 
111  scalar disc = sqr(radius_) - (magSqrToCentre - sqr(v));
112 
113  if (disc >= 0)
114  {
115  scalar d = Foam::sqrt(disc);
116 
117  scalar nearParam = v-d;
118 
119  if (nearParam >= 0 && sqr(nearParam) <= magSqrDir)
120  {
121  near.setHit();
122  near.setPoint(start + nearParam*dir);
123  near.setIndex(0);
124  }
125 
126  scalar farParam = v+d;
127 
128  if (farParam >= 0 && sqr(farParam) <= magSqrDir)
129  {
130  far.setHit();
131  far.setPoint(start + farParam*dir);
132  far.setIndex(0);
133  }
134  }
135  }
136 }
137 
138 
139 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
140 
142 (
143  const IOobject& io,
144  const point& centre,
145  const scalar radius
146 )
147 :
148  searchableSurface(io),
149  centre_(centre),
150  radius_(radius)
151 {
152  bounds() = boundBox
153  (
154  centre_ - radius_*vector::one,
155  centre_ + radius_*vector::one
156  );
157 }
158 
159 
161 (
162  const IOobject& io,
163  const dictionary& dict
164 )
165 :
166  searchableSurface(io),
167  centre_(dict.lookup<point>("centre", dimLength)),
168  radius_(dict.lookup<scalar>("radius", dimLength))
169 {
170  bounds() = boundBox
171  (
172  centre_ - radius_*vector::one,
173  centre_ + radius_*vector::one
174  );
175 }
176 
177 
178 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
179 
181 {}
182 
183 
184 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
185 
187 {
188  return bb.overlaps(centre_, sqr(radius_));
189 }
190 
191 
193 {
194  if (regions_.empty())
195  {
196  regions_.setSize(1);
197  regions_[0] = "region0";
198  }
199  return regions_;
200 }
201 
202 
203 
205 (
206  pointField& centres,
207  scalarField& radiusSqr
208 ) const
209 {
210  centres.setSize(1);
211  centres[0] = centre_;
212 
213  radiusSqr.setSize(1);
214  radiusSqr[0] = Foam::sqr(radius_);
215 
216  // Add a bit to make sure all points are tested inside
217  radiusSqr += Foam::sqr(small);
218 }
219 
220 
221 void Foam::searchableSurfaces::sphere::findNearest
222 (
223  const pointField& samples,
224  const scalarField& nearestDistSqr,
225  List<pointIndexHit>& info
226 ) const
227 {
228  info.setSize(samples.size());
229 
230  forAll(samples, i)
231  {
232  info[i] = findNearest(samples[i], nearestDistSqr[i]);
233  }
234 }
235 
236 
238 (
239  const pointField& start,
240  const pointField& end,
241  List<pointIndexHit>& info
242 ) const
243 {
244  info.setSize(start.size());
245 
247 
248  forAll(start, i)
249  {
250  // Pick nearest intersection. If none intersected take second one.
251  findLineAll(start[i], end[i], info[i], b);
252  if (!info[i].hit() && b.hit())
253  {
254  info[i] = b;
255  }
256  }
257 }
258 
259 
261 (
262  const pointField& start,
263  const pointField& end,
264  List<pointIndexHit>& info
265 ) const
266 {
267  info.setSize(start.size());
268 
270 
271  forAll(start, i)
272  {
273  // Discard far intersection
274  findLineAll(start[i], end[i], info[i], b);
275  if (!info[i].hit() && b.hit())
276  {
277  info[i] = b;
278  }
279  }
280 }
281 
282 
283 void Foam::searchableSurfaces::sphere::findLineAll
284 (
285  const pointField& start,
286  const pointField& end,
288 ) const
289 {
290  info.setSize(start.size());
291 
292  forAll(start, i)
293  {
294  pointIndexHit near, far;
295  findLineAll(start[i], end[i], near, far);
296 
297  if (near.hit())
298  {
299  if (far.hit())
300  {
301  info[i].setSize(2);
302  info[i][0] = near;
303  info[i][1] = far;
304  }
305  else
306  {
307  info[i].setSize(1);
308  info[i][0] = near;
309  }
310  }
311  else
312  {
313  if (far.hit())
314  {
315  info[i].setSize(1);
316  info[i][0] = far;
317  }
318  else
319  {
320  info[i].clear();
321  }
322  }
323  }
324 }
325 
326 
328 (
329  const List<pointIndexHit>& info,
330  labelList& region
331 ) const
332 {
333  region.setSize(info.size());
334  region = 0;
335 }
336 
337 
339 (
340  const List<pointIndexHit>& info,
341  vectorField& normal
342 ) const
343 {
344  normal.setSize(info.size());
345  normal = Zero;
346 
347  forAll(info, i)
348  {
349  if (info[i].hit())
350  {
351  normal[i] = info[i].hitPoint() - centre_;
352 
353  normal[i] /= mag(normal[i])+vSmall;
354  }
355  else
356  {
357  // Set to what?
358  }
359  }
360 }
361 
362 
364 (
365  const pointField& points,
366  List<volumeType>& volType
367 ) const
368 {
369  volType.setSize(points.size());
370  volType = volumeType::inside;
371 
372  forAll(points, pointi)
373  {
374  const point& pt = points[pointi];
375 
376  if (magSqr(pt - centre_) <= sqr(radius_))
377  {
378  volType[pointi] = volumeType::inside;
379  }
380  else
381  {
382  volType[pointi] = volumeType::outside;
383  }
384  }
385 }
386 
387 
388 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Macros for easy insertion into run-time selection tables.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
InfoProxy< IOobject > info() const
Return info proxy.
Definition: IOobject.H:485
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:54
bool hit() const
Is there a hit.
static const Form one
Definition: VectorSpace.H:119
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:59
bool overlaps(const boundBox &) const
Overlaps/touches boundingBox?
Definition: boundBoxI.H:126
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
const boundBox & bounds() const
Return const reference to boundBox.
Surface geometry with a sphere shape, which can be used with snappyHexMesh.
sphere(const IOobject &io, const point &, const scalar radius)
Construct from components.
virtual void getVolumeType(const pointField &, List< volumeType > &) const
Determine type (inside/outside/mixed) for point. unknown if.
virtual void findLine(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Find first intersection on segment from start to end.
virtual bool overlaps(const boundBox &bb) const
Does any part of the surface overlap the supplied bound box?
virtual void findLineAny(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Return any intersection on segment from start to end.
virtual void boundingSpheres(pointField &centres, scalarField &radiusSqr) const
Get bounding spheres (centre and radius squared), one per element.
virtual void getNormal(const List< pointIndexHit > &, vectorField &normal) const
From a set of points and indices get the normal.
virtual void getRegion(const List< pointIndexHit > &, labelList &region) const
From a set of points and indices get the region.
virtual const wordList & regions() const
Names of regions.
const pointField & points
volScalarField & b
Definition: createFields.H:27
addToRunTimeSelectionTable(searchableSurface, box, dictionary)
addBackwardCompatibleToRunTimeSelectionTable(searchableSurface, box, dictionary, searchableBox, "searchableBox")
Namespace for OpenFOAM.
static const zero Zero
Definition: zero.H:97
PointIndexHit< point > pointIndexHit
Definition: pointIndexHit.H:42
const dimensionSet dimLength
vector point
Point is a vector.
Definition: point.H:41
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
void sqr(LagrangianPatchField< typename outerProduct< Type, Type >::type > &f, const LagrangianPatchField< Type > &f1)
void magSqr(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
void sqrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
dictionary dict
scalarField samples(nIntervals, 0)