BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / meshTools / searchableSurface / searchableSurfaceWithGaps.C
blob6e40feb9efe31ec4ff4014cd0416c50ae41c6eb3
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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"
28 #include "Time.H"
29 #include "ListOps.H"
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 namespace Foam
36 defineTypeNameAndDebug(searchableSurfaceWithGaps, 0);
37 addToRunTimeSelectionTable(searchableSurface, searchableSurfaceWithGaps, dict);
42 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
44 Foam::Pair<Foam::vector> Foam::searchableSurfaceWithGaps::offsetVecs
46     const point& start,
47     const point& end
48 ) const
50     Pair<vector> offsets(vector::zero, vector::zero);
52     vector n(end-start);
54     scalar magN = mag(n);
56     if (magN > SMALL)
57     {
58         n /= magN;
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++)
66         {
67             if (mag(n[cmpt]) < minMag)
68             {
69                 minMag = mag(n[cmpt]);
70                 minCmpt = cmpt;
71             }
72         }
74         offsets[0][minCmpt] = 1.0;
75         // Orthonormalise
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];
81         // Scale
82         offsets[0] *= gap_;
83         offsets[1] *= gap_;
84     }
86     return offsets;
90 void Foam::searchableSurfaceWithGaps::offsetVecs
92     const pointField& start,
93     const pointField& end,
94     pointField& offset0,
95     pointField& offset1
96 ) const
98     offset0.setSize(start.size());
99     offset1.setSize(start.size());
101     forAll(start, i)
102     {
103         const Pair<vector> offsets(offsetVecs(start[i], end[i]));
104         offset0[i] = offsets[0];
105         offset1[i] = offsets[1];
106     }
110 Foam::label Foam::searchableSurfaceWithGaps::countMisses
112     const List<pointIndexHit>& info,
113     labelList& missMap
116     label nMiss = 0;
117     forAll(info, i)
118     {
119         if (!info[i].hit())
120         {
121             nMiss++;
122         }
123     }
125     missMap.setSize(nMiss);
126     nMiss = 0;
128     forAll(info, i)
129     {
130         if (!info[i].hit())
131         {
132             missMap[nMiss++] = i;
133         }
134     }
136     return nMiss;
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,
145     labelList& missMap
148     label nMiss = 0;
149     forAll(plusInfo, i)
150     {
151         if (!plusInfo[i].hit() || !minInfo[i].hit())
152         {
153             nMiss++;
154         }
155     }
157     missMap.setSize(nMiss);
158     nMiss = 0;
160     forAll(plusInfo, i)
161     {
162         if (!plusInfo[i].hit() || !minInfo[i].hit())
163         {
164             missMap[nMiss++] = i;
165         }
166     }
168     return nMiss;
172 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
174 Foam::searchableSurfaceWithGaps::searchableSurfaceWithGaps
176     const IOobject& io,
177     const dictionary& dict
180     searchableSurface(io),
181     gap_(readScalar(dict.lookup("gap"))),
182     subGeom_(1)
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
206 ) const
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)
219     {
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;
229         offsetVecs
230         (
231             compactStart,
232             compactEnd,
233             offset0,
234             offset1
235         );
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;
246         surface().findLine
247         (
248             compactStart+offset0-smallVec,
249             compactEnd+offset0+smallVec,
250             plusInfo
251         );
252         List<pointIndexHit> minInfo;
253         surface().findLine
254         (
255             compactStart-offset0-smallVec,
256             compactEnd-offset0+smallVec,
257             minInfo
258         );
260         // Extract any hits
261         forAll(plusInfo, i)
262         {
263             if (plusInfo[i].hit() && minInfo[i].hit())
264             {
265                 info[compactMap[i]] = plusInfo[i];
266                 info[compactMap[i]].rawPoint() -= offset0[i];
267             }
268         }
270         labelList plusMissMap;
271         nMiss = countMisses(plusInfo, minInfo, plusMissMap);
273         if (returnReduce(nMiss, sumOp<label>()) > 0)
274         {
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)
283             {
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];
290             }
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));
299             surface().findLine
300             (
301                 compactStart+offset1-smallVec,
302                 compactEnd+offset1+smallVec,
303                 plusInfo
304             );
305             surface().findLine
306             (
307                 compactStart-offset1-smallVec,
308                 compactEnd-offset1+smallVec,
309                 minInfo
310             );
312             // Extract any hits
313             forAll(plusInfo, i)
314             {
315                 if (plusInfo[i].hit() && minInfo[i].hit())
316                 {
317                     info[compactMap[i]] = plusInfo[i];
318                     info[compactMap[i]].rawPoint() -= offset1[i];
319                 }
320             }
321         }
322     }
326 void Foam::searchableSurfaceWithGaps::findLineAny
328     const pointField& start,
329     const pointField& end,
330     List<pointIndexHit>& info
331 ) const
333     // To be done ...
334     findLine(start, end, info);
338 void Foam::searchableSurfaceWithGaps::findLineAll
340     const pointField& start,
341     const pointField& end,
342     List<List<pointIndexHit> >& info
343 ) const
345     // To be done. Assume for now only one intersection.
346     List<pointIndexHit> nearestInfo;
347     findLine(start, end, nearestInfo);
349     info.setSize(start.size());
350     forAll(info, pointI)
351     {
352         if (nearestInfo[pointI].hit())
353         {
354             info[pointI].setSize(1);
355             info[pointI][0] = nearestInfo[pointI];
356         }
357         else
358         {
359             info[pointI].clear();
360         }
361     }
365 // ************************************************************************* //