BUGFIX: Illegal use of uninitialised value (backport)
[foam-extend-3.2.git] / src / dynamicMesh / dynamicFvMesh / dynamicTopoFvMesh / convexSetAlgorithm / tetIntersectionI.H
blob57e3625747cb23e2785c9ddaf26f42f856c9e528
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
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 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
19     for more details.
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 Implemented by
26     Sandeep Menon
27     University of Massachusetts Amherst
29 \*---------------------------------------------------------------------------*/
31 namespace Foam
34 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
36 // Compute clip-planes
37 inline void tetIntersection::computeClipPlanes()
39     // Define edge vectors
40     vector edge10 = clipTet_[1] - clipTet_[0];
41     vector edge20 = clipTet_[2] - clipTet_[0];
42     vector edge30 = clipTet_[3] - clipTet_[0];
43     vector edge21 = clipTet_[2] - clipTet_[1];
44     vector edge31 = clipTet_[3] - clipTet_[1];
46     // Cross-products
47     clipPlanes_[0].first() = (edge20 ^ edge10);
48     clipPlanes_[1].first() = (edge10 ^ edge30);
49     clipPlanes_[2].first() = (edge30 ^ edge20);
50     clipPlanes_[3].first() = (edge21 ^ edge31);
52     // Normalize
53     clipPlanes_[0].first() /= mag(clipPlanes_[0].first()) + VSMALL;
54     clipPlanes_[1].first() /= mag(clipPlanes_[1].first()) + VSMALL;
55     clipPlanes_[2].first() /= mag(clipPlanes_[2].first()) + VSMALL;
56     clipPlanes_[3].first() /= mag(clipPlanes_[3].first()) + VSMALL;
58     // Compute magnitude of clipping tetrahedron
59     clipTetMag_ = (1.0 / 6.0) * (edge10 & clipPlanes_[3].first());
61     if (clipTetMag_ < 0.0)
62     {
63         // Reverse normal directions
64         clipPlanes_[0].first() = -clipPlanes_[0].first();
65         clipPlanes_[1].first() = -clipPlanes_[1].first();
66         clipPlanes_[2].first() = -clipPlanes_[2].first();
67         clipPlanes_[3].first() = -clipPlanes_[3].first();
69         // Reverse sign
70         clipTetMag_ = mag(clipTetMag_);
71     }
73     // Determine plane constants
74     clipPlanes_[0].second() = (clipTet_[0] & clipPlanes_[0].first());
75     clipPlanes_[1].second() = (clipTet_[1] & clipPlanes_[1].first());
76     clipPlanes_[2].second() = (clipTet_[2] & clipPlanes_[2].first());
77     clipPlanes_[3].second() = (clipTet_[3] & clipPlanes_[3].first());
81 // Split and decompose
82 inline void tetIntersection::splitAndDecompose
84     const label tetPlaneIndex,
85     FixedList<point, 4>& tetra,
86     DynamicList<FixedList<point, 4> >& decompTets
87 ) const
89     FixedList<scalar, 4> C;
90     FixedList<vector, 4> tmpTetra;
91     FixedList<label, 4> pos, neg, zero;
92     label i = 0, nPos = 0, nNeg = 0, nZero = 0;
94     // Fetch reference to plane
95     const hPlane& tetPlane = clipPlanes_[tetPlaneIndex];
97     for (i = 0; i < 4; ++i)
98     {
99         // Compute distance to plane
100         C[i] = (tetra[i] & tetPlane.first()) - tetPlane.second();
102         if (C[i] > 0.0)
103         {
104             pos[nPos++] = i;
105         }
106         else
107         if (C[i] < 0.0)
108         {
109             neg[nNeg++] = i;
110         }
111         else
112         {
113             zero[nZero++] = i;
114         }
115     }
117     if (nNeg == 0)
118     {
119         return;
120     }
122     if (nPos == 0)
123     {
124         decompTets.append(tetra);
125         return;
126     }
128     // Tetrahedron is split by plane.  Determine how it is split and how to
129     // decompose the negative-side portion into tetrahedra (6 cases).
130     scalar w0, w1, invCDiff;
131     vector intp[4];
133     if (nPos == 3)
134     {
135         // +++-
136         for (i = 0; i < nPos; ++i)
137         {
138             invCDiff = (1.0 / (C[pos[i]] - C[neg[0]]));
140             w0 = -C[neg[0]] * invCDiff;
141             w1 = +C[pos[i]] * invCDiff;
143             tetra[pos[i]] = (w0 * tetra[pos[i]]) + (w1 * tetra[neg[0]]);
144         }
146         decompTets.append(tetra);
147     }
148     else
149     if (nPos == 2)
150     {
151         if (nNeg == 2)
152         {
153             // ++--
154             for (i = 0; i < nPos; ++i)
155             {
156                 invCDiff = (1.0 / (C[pos[i]] - C[neg[0]]));
158                 w0 = -C[neg[0]] * invCDiff;
159                 w1 = +C[pos[i]] * invCDiff;
161                 intp[i] = (w0 * tetra[pos[i]]) + (w1 * tetra[neg[0]]);
162             }
164             for (i = 0; i < nNeg; ++i)
165             {
166                 invCDiff = (1.0 / (C[pos[i]] - C[neg[1]]));
168                 w0 = -C[neg[1]] * invCDiff;
169                 w1 = +C[pos[i]] * invCDiff;
171                 intp[i+2] = (w0 * tetra[pos[i]]) + (w1 * tetra[neg[1]]);
172             }
174             tetra[pos[0]] = intp[2];
175             tetra[pos[1]] = intp[1];
177             decompTets.append(tetra);
179             tmpTetra[0] = tetra[neg[1]];
180             tmpTetra[1] = intp[3];
181             tmpTetra[2] = intp[2];
182             tmpTetra[3] = intp[1];
184             decompTets.append(tmpTetra);
186             tmpTetra[0] = tetra[neg[0]];
187             tmpTetra[1] = intp[0];
188             tmpTetra[2] = intp[1];
189             tmpTetra[3] = intp[2];
191             decompTets.append(tmpTetra);
192         }
193         else
194         {
195             // ++-0
196             for (i = 0; i < nPos; ++i)
197             {
198                 invCDiff = (1.0 / (C[pos[i]] - C[neg[0]]));
200                 w0 = -C[neg[0]] * invCDiff;
201                 w1 = +C[pos[i]] * invCDiff;
203                 tetra[pos[i]] = (w0 * tetra[pos[i]]) + (w1 * tetra[neg[0]]);
204             }
206             decompTets.append(tetra);
207         }
208     }
209     else
210     if (nPos == 1)
211     {
212         if (nNeg == 3)
213         {
214             // +---
215             for (i = 0; i < nNeg; ++i)
216             {
217                 invCDiff = (1.0 / (C[pos[0]] - C[neg[i]]));
219                 w0 = -C[neg[i]] * invCDiff;
220                 w1 = +C[pos[0]] * invCDiff;
222                 intp[i] = (w0 * tetra[pos[0]]) + (w1 * tetra[neg[i]]);
223             }
225             tetra[pos[0]] = intp[0];
227             decompTets.append(tetra);
229             tmpTetra[0] = intp[0];
230             tmpTetra[1] = tetra[neg[1]];
231             tmpTetra[2] = tetra[neg[2]];
232             tmpTetra[3] = intp[1];
234             decompTets.append(tmpTetra);
236             tmpTetra[0] = tetra[neg[2]];
237             tmpTetra[1] = intp[1];
238             tmpTetra[2] = intp[2];
239             tmpTetra[3] = intp[0];
241             decompTets.append(tmpTetra);
242         }
243         else
244         if (nNeg == 2)
245         {
246             // +--0
247             for (i = 0; i < nNeg; ++i)
248             {
249                 invCDiff = (1.0 / (C[pos[0]] - C[neg[i]]));
251                 w0 = -C[neg[i]] * invCDiff;
252                 w1 = +C[pos[0]] * invCDiff;
254                 intp[i] = (w0 * tetra[pos[0]]) + (w1 * tetra[neg[i]]);
255             }
257             tetra[pos[0]] = intp[0];
259             decompTets.append(tetra);
261             tmpTetra[0] = intp[1];
262             tmpTetra[1] = tetra[zero[0]];
263             tmpTetra[2] = tetra[neg[1]];
264             tmpTetra[3] = intp[0];
266             decompTets.append(tmpTetra);
267         }
268         else
269         {
270             // +-00
271             invCDiff = (1.0 / (C[pos[0]] - C[neg[0]]));
273             w0 = -C[neg[0]] * invCDiff;
274             w1 = +C[pos[0]] * invCDiff;
276             tetra[pos[0]] = (w0 * tetra[pos[0]]) + (w1 * tetra[neg[0]]);
278             decompTets.append(tetra);
279         }
280     }
284 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
286 inline tetIntersection::tetIntersection(const FixedList<point, 4>& clipTet)
288     clipTet_(clipTet),
289     clipTetMag_(0.0),
290     inside_(10),
291     allTets_(10)
293     // Pre-compute clipping planes
294     computeClipPlanes();
298 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
300 inline tetIntersection::~tetIntersection()
304 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
306 // Return magnitude of clipping tetrahedron
307 inline scalar tetIntersection::clipTetMag() const
309     return clipTetMag_;
313 // Evaluate for intersections
314 inline bool tetIntersection::evaluate(const FixedList<point, 4>& subjectTet)
316     // Clear lists
317     inside_.clear();
318     allTets_.clear();
320     // Add initial tetrahedron to list
321     allTets_.append(subjectTet);
323     // Clip second tetrahedron against planes of clipping tetrahedron
324     for (label i = 0; i < 4; i++)
325     {
326         forAll(allTets_, tetI)
327         {
328             splitAndDecompose(i, allTets_[tetI], inside_);
329         }
331         // Prep for next clipping plane
332         allTets_ = inside_;
333         inside_.clear();
334     }
336     return (allTets_.size() > 0);
340 // Return intersections
341 inline const DynamicList<FixedList<point, 4> >&
342 tetIntersection::getIntersection() const
344     return allTets_;
348 //- Evaluate and return volume / centroid
349 inline void tetIntersection::getVolumeAndCentre
351     scalar& volume,
352     vector& centre
353 ) const
355     volume = 0.0;
356     centre = vector::zero;
358     forAll(allTets_, tetI)
359     {
360         const FixedList<point, 4>& t = allTets_[tetI];
362         // Calculate volume (no check for orientation)
363         scalar tV =
364         (
365             Foam::mag
366             (
367                 (1.0/6.0) *
368                 (
369                     ((t[1] - t[0]) ^ (t[2] - t[0])) & (t[3] - t[0])
370                 )
371             )
372         );
374         // Calculate centroid
375         vector tC = (0.25 * (t[0] + t[1] + t[2] + t[3]));
377         volume += tV;
378         centre += (tV * tC);
379     }
381     centre /= volume + VSMALL;
387 // ************************************************************************* //