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 "searchableSurfaceWithGaps.H"
28 #include "addToRunTimeSelectionTable.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 defineTypeNameAndDebug(searchableSurfaceWithGaps, 0);
38 addToRunTimeSelectionTable(searchableSurface, searchableSurfaceWithGaps, dict);
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45 Foam::Pair<Foam::vector> Foam::searchableSurfaceWithGaps::offsetVecs
51 Pair<vector> offsets(vector::zero, vector::zero);
61 // Do first offset vector. Is the coordinate axes with the smallest
62 // component along the vector n.
63 scalar minMag = GREAT;
64 direction minCmpt = 0;
66 for (direction cmpt = 0; cmpt < vector::nComponents; cmpt++)
68 if (mag(n[cmpt]) < minMag)
70 minMag = mag(n[cmpt]);
75 offsets[0][minCmpt] = 1.0;
77 offsets[0] -= n[minCmpt]*n;
79 offsets[0] *= gap_/mag(offsets[0]);
82 // Do second offset vector perp to original edge and first offset vector
83 offsets[1] = n ^ offsets[0];
91 void Foam::searchableSurfaceWithGaps::offsetVecs
93 const pointField& start,
94 const pointField& end,
99 offset0.setSize(start.size());
100 offset1.setSize(start.size());
104 const Pair<vector> offsets(offsetVecs(start[i], end[i]));
105 offset0[i] = offsets[0];
106 offset1[i] = offsets[1];
111 Foam::label Foam::searchableSurfaceWithGaps::countMisses
113 const List<pointIndexHit>& info,
126 missMap.setSize(nMiss);
133 missMap[nMiss++] = i;
141 // Anything not a hit in both counts as a hit
142 Foam::label Foam::searchableSurfaceWithGaps::countMisses
144 const List<pointIndexHit>& plusInfo,
145 const List<pointIndexHit>& minInfo,
152 if (!plusInfo[i].hit() || !minInfo[i].hit())
158 missMap.setSize(nMiss);
163 if (!plusInfo[i].hit() || !minInfo[i].hit())
165 missMap[nMiss++] = i;
173 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
175 Foam::searchableSurfaceWithGaps::searchableSurfaceWithGaps
178 const dictionary& dict
181 searchableSurface(io),
182 gap_(readScalar(dict.lookup("gap"))),
185 const word subGeomName(dict.lookup("surface"));
187 const searchableSurface& s =
188 io.db().lookupObject<searchableSurface>(subGeomName);
190 subGeom_.set(0, &const_cast<searchableSurface&>(s));
194 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
196 Foam::searchableSurfaceWithGaps::~searchableSurfaceWithGaps()
200 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
202 void Foam::searchableSurfaceWithGaps::findLine
204 const pointField& start,
205 const pointField& end,
206 List<pointIndexHit>& info
210 // Test with unperturbed vectors
211 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
213 surface().findLine(start, end, info);
215 // Count number of misses. Determine map
216 labelList compactMap;
217 label nMiss = countMisses(info, compactMap);
219 if (returnReduce(nMiss, sumOp<label>()) > 0)
221 //Pout<< "** retesting with offset0 " << nMiss << " misses out of "
222 // << start.size() << endl;
224 // extract segments according to map
225 pointField compactStart(start, compactMap);
226 pointField compactEnd(end, compactMap);
228 // Calculate offset vector
229 pointField offset0, offset1;
238 // Test with offset0 perturbed vectors
239 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241 // test in pairs: only if both perturbations hit something
242 // do we accept the hit.
244 const vectorField smallVec(SMALL*(compactEnd-compactStart));
246 List<pointIndexHit> plusInfo;
249 compactStart+offset0-smallVec,
250 compactEnd+offset0+smallVec,
253 List<pointIndexHit> minInfo;
256 compactStart-offset0-smallVec,
257 compactEnd-offset0+smallVec,
264 if (plusInfo[i].hit() && minInfo[i].hit())
266 info[compactMap[i]] = plusInfo[i];
267 info[compactMap[i]].rawPoint() -= offset0[i];
271 labelList plusMissMap;
272 nMiss = countMisses(plusInfo, minInfo, plusMissMap);
274 if (returnReduce(nMiss, sumOp<label>()) > 0)
276 //Pout<< "** retesting with offset1 " << nMiss << " misses out of "
277 // << start.size() << endl;
279 // Test with offset1 perturbed vectors
280 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
282 // Extract (inplace possible because of order)
283 forAll(plusMissMap, i)
285 label mapI = plusMissMap[i];
286 compactStart[i] = compactStart[mapI];
287 compactEnd[i] = compactEnd[mapI];
288 compactMap[i] = compactMap[mapI];
289 offset0[i] = offset0[mapI];
290 offset1[i] = offset1[mapI];
292 compactStart.setSize(plusMissMap.size());
293 compactEnd.setSize(plusMissMap.size());
294 compactMap.setSize(plusMissMap.size());
295 offset0.setSize(plusMissMap.size());
296 offset1.setSize(plusMissMap.size());
298 const vectorField smallVec(SMALL*(compactEnd-compactStart));
302 compactStart+offset1-smallVec,
303 compactEnd+offset1+smallVec,
308 compactStart-offset1-smallVec,
309 compactEnd-offset1+smallVec,
316 if (plusInfo[i].hit() && minInfo[i].hit())
318 info[compactMap[i]] = plusInfo[i];
319 info[compactMap[i]].rawPoint() -= offset1[i];
327 void Foam::searchableSurfaceWithGaps::findLineAny
329 const pointField& start,
330 const pointField& end,
331 List<pointIndexHit>& info
335 findLine(start, end, info);
339 void Foam::searchableSurfaceWithGaps::findLineAll
341 const pointField& start,
342 const pointField& end,
343 List<List<pointIndexHit> >& info
346 // To be done. Assume for now only one intersection.
347 List<pointIndexHit> nearestInfo;
348 findLine(start, end, nearestInfo);
350 info.setSize(start.size());
353 if (nearestInfo[pointI].hit())
355 info[pointI].setSize(1);
356 info[pointI][0] = nearestInfo[pointI];
360 info[pointI].clear();
366 // ************************************************************************* //