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 "searchableSurfaceWithGaps.H"
27 #include "addToRunTimeSelectionTable.H"
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 defineTypeNameAndDebug(searchableSurfaceWithGaps, 0);
37 addToRunTimeSelectionTable(searchableSurface, searchableSurfaceWithGaps, dict);
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 Foam::Pair<Foam::vector> Foam::searchableSurfaceWithGaps::offsetVecs
50 Pair<vector> offsets(vector::zero, vector::zero);
60 // Do first offset vector. Is the coordinate axes with the smallest
61 // component along the vector n.
62 scalar minMag = GREAT;
63 direction minCmpt = 0;
65 for (direction cmpt = 0; cmpt < vector::nComponents; cmpt++)
67 if (mag(n[cmpt]) < minMag)
69 minMag = mag(n[cmpt]);
74 offsets[0][minCmpt] = 1.0;
76 offsets[0] -= n[minCmpt]*n;
77 offsets[0] /= mag(offsets[0]);
78 // Do second offset vector perp to original edge and first offset vector
79 offsets[1] = n ^ offsets[0];
90 void Foam::searchableSurfaceWithGaps::offsetVecs
92 const pointField& start,
93 const pointField& end,
98 offset0.setSize(start.size());
99 offset1.setSize(start.size());
103 const Pair<vector> offsets(offsetVecs(start[i], end[i]));
104 offset0[i] = offsets[0];
105 offset1[i] = offsets[1];
110 Foam::label Foam::searchableSurfaceWithGaps::countMisses
112 const List<pointIndexHit>& info,
125 missMap.setSize(nMiss);
132 missMap[nMiss++] = i;
140 // Anything not a hit in both counts as a hit
141 Foam::label Foam::searchableSurfaceWithGaps::countMisses
143 const List<pointIndexHit>& plusInfo,
144 const List<pointIndexHit>& minInfo,
151 if (!plusInfo[i].hit() || !minInfo[i].hit())
157 missMap.setSize(nMiss);
162 if (!plusInfo[i].hit() || !minInfo[i].hit())
164 missMap[nMiss++] = i;
172 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
174 Foam::searchableSurfaceWithGaps::searchableSurfaceWithGaps
177 const dictionary& dict
180 searchableSurface(io),
181 gap_(readScalar(dict.lookup("gap"))),
184 const word subGeomName(dict.lookup("surface"));
186 const searchableSurface& s =
187 io.db().lookupObject<searchableSurface>(subGeomName);
189 subGeom_.set(0, &const_cast<searchableSurface&>(s));
193 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
195 Foam::searchableSurfaceWithGaps::~searchableSurfaceWithGaps()
199 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
201 void Foam::searchableSurfaceWithGaps::findLine
203 const pointField& start,
204 const pointField& end,
205 List<pointIndexHit>& info
209 // Test with unperturbed vectors
210 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212 surface().findLine(start, end, info);
214 // Count number of misses. Determine map
215 labelList compactMap;
216 label nMiss = countMisses(info, compactMap);
218 if (returnReduce(nMiss, sumOp<label>()) > 0)
220 //Pout<< "** retesting with offset0 " << nMiss << " misses out of "
221 // << start.size() << endl;
223 // extract segments according to map
224 pointField compactStart(start, compactMap);
225 pointField compactEnd(end, compactMap);
227 // Calculate offset vector
228 pointField offset0, offset1;
237 // Test with offset0 perturbed vectors
238 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
240 // test in pairs: only if both perturbations hit something
241 // do we accept the hit.
243 const vectorField smallVec(1E-6*(compactEnd-compactStart));
245 List<pointIndexHit> plusInfo;
248 compactStart+offset0-smallVec,
249 compactEnd+offset0+smallVec,
252 List<pointIndexHit> minInfo;
255 compactStart-offset0-smallVec,
256 compactEnd-offset0+smallVec,
263 if (plusInfo[i].hit() && minInfo[i].hit())
265 info[compactMap[i]] = plusInfo[i];
266 info[compactMap[i]].rawPoint() -= offset0[i];
270 labelList plusMissMap;
271 nMiss = countMisses(plusInfo, minInfo, plusMissMap);
273 if (returnReduce(nMiss, sumOp<label>()) > 0)
275 //Pout<< "** retesting with offset1 " << nMiss << " misses out of "
276 // << start.size() << endl;
278 // Test with offset1 perturbed vectors
279 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
281 // Extract (inplace possible because of order)
282 forAll(plusMissMap, i)
284 label mapI = plusMissMap[i];
285 compactStart[i] = compactStart[mapI];
286 compactEnd[i] = compactEnd[mapI];
287 compactMap[i] = compactMap[mapI];
288 offset0[i] = offset0[mapI];
289 offset1[i] = offset1[mapI];
291 compactStart.setSize(plusMissMap.size());
292 compactEnd.setSize(plusMissMap.size());
293 compactMap.setSize(plusMissMap.size());
294 offset0.setSize(plusMissMap.size());
295 offset1.setSize(plusMissMap.size());
297 const vectorField smallVec(1E-6*(compactEnd-compactStart));
301 compactStart+offset1-smallVec,
302 compactEnd+offset1+smallVec,
307 compactStart-offset1-smallVec,
308 compactEnd-offset1+smallVec,
315 if (plusInfo[i].hit() && minInfo[i].hit())
317 info[compactMap[i]] = plusInfo[i];
318 info[compactMap[i]].rawPoint() -= offset1[i];
326 void Foam::searchableSurfaceWithGaps::findLineAny
328 const pointField& start,
329 const pointField& end,
330 List<pointIndexHit>& info
334 findLine(start, end, info);
338 void Foam::searchableSurfaceWithGaps::findLineAll
340 const pointField& start,
341 const pointField& end,
342 List<List<pointIndexHit> >& info
345 // To be done. Assume for now only one intersection.
346 List<pointIndexHit> nearestInfo;
347 findLine(start, end, nearestInfo);
349 info.setSize(start.size());
352 if (nearestInfo[pointI].hit())
354 info[pointI].setSize(1);
355 info[pointI][0] = nearestInfo[pointI];
359 info[pointI].clear();
365 // ************************************************************************* //