Loading...
Searching...
No Matches
tetOverlapVolumeTemplates.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2015 OpenFOAM Foundation
9 Copyright (C) 2016 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "tetOverlapVolume.H"
30#include "primitiveMesh.H"
31
32// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
33
34template<class tetPointsOp>
35void Foam::tetOverlapVolume::tetTetOverlap
36(
37 const tetPoints& tetA,
38 const tetPoints& tetB,
39 tetPointsOp& insideOp
40)
41{
42 static tetPointRef::tetIntersectionList insideTets;
43 label nInside = 0;
44 static tetPointRef::tetIntersectionList cutInsideTets;
45 label nCutInside = 0;
46
47 tetPointRef::storeOp inside(insideTets, nInside);
48 tetPointRef::storeOp cutInside(cutInsideTets, nCutInside);
49 tetPointRef::dummyOp outside;
50
51 // Precompute the tet face areas and exit early if any face area is
52 // too small
53 static FixedList<vector, 4> tetAFaceAreas;
54 static FixedList<scalar, 4> tetAMag2FaceAreas;
55 tetPointRef tetATet = tetA.tet();
56 for (label facei = 0; facei < 4; ++facei)
57 {
58 tetAFaceAreas[facei] = -tetATet.tri(facei).areaNormal();
59 tetAMag2FaceAreas[facei] = magSqr(tetAFaceAreas[facei]);
60 if (tetAMag2FaceAreas[facei] < ROOTVSMALL)
61 {
62 return;
63 }
64 }
65
66 static FixedList<vector, 4> tetBFaceAreas;
67 static FixedList<scalar, 4> tetBMag2FaceAreas;
68 tetPointRef tetBTet = tetB.tet();
69 for (label facei = 0; facei < 4; ++facei)
70 {
71 tetBFaceAreas[facei] = -tetBTet.tri(facei).areaNormal();
72 tetBMag2FaceAreas[facei] = magSqr(tetBFaceAreas[facei]);
73 if (tetBMag2FaceAreas[facei] < ROOTVSMALL)
74 {
75 return;
76 }
77 }
78
79
80 // Face 0
81 {
82 vector n = tetBFaceAreas[0]/Foam::sqrt(tetBMag2FaceAreas[0]);
83 plane pl0(tetBTet.tri(0).a(), n, false);
84
85 tetA.tet().sliceWithPlane(pl0, cutInside, outside);
86 if (nCutInside == 0)
87 {
88 return;
89 }
90 }
91
92 // Face 1
93 {
94 vector n = tetBFaceAreas[1]/Foam::sqrt(tetBMag2FaceAreas[1]);
95 plane pl1(tetBTet.tri(1).a(), n, false);
96
97 nInside = 0;
98 for (label i = 0; i < nCutInside; i++)
99 {
100 const tetPointRef t = cutInsideTets[i].tet();
101 t.sliceWithPlane(pl1, inside, outside);
102 }
103 if (nInside == 0)
104 {
105 return;
106 }
107 }
108
109 // Face 2
110 {
111 vector n = tetBFaceAreas[2]/Foam::sqrt(tetBMag2FaceAreas[2]);
112 plane pl2(tetBTet.tri(2).a(), n, false);
113
114 nCutInside = 0;
115 for (label i = 0; i < nInside; i++)
116 {
117 const tetPointRef t = insideTets[i].tet();
118 t.sliceWithPlane(pl2, cutInside, outside);
119 }
120 if (nCutInside == 0)
121 {
122 return;
123 }
124 }
125
126 // Face 3
127 {
128 vector n = tetBFaceAreas[3]/Foam::sqrt(tetBMag2FaceAreas[3]);
129 plane pl3(tetBTet.tri(3).a(), n, false);
130 for (label i = 0; i < nCutInside; i++)
131 {
132 const tetPointRef t = cutInsideTets[i].tet();
133 t.sliceWithPlane(pl3, insideOp, outside);
134 }
135 }
136}
137
138
139template<class tetsOp>
140void Foam::tetOverlapVolume::cellCellOverlapMinDecomp
141(
142 const primitiveMesh& meshA,
143 const label cellAI,
144
145 const primitiveMesh& meshB,
146 const label cellBI,
147 const treeBoundBox& cellBbB,
148 tetsOp& combineTetsOp
149)
150{
151 const cell& cFacesA = meshA.cells()[cellAI];
152 const point& ccA = meshA.cellCentres()[cellAI];
153
154 const cell& cFacesB = meshB.cells()[cellBI];
155 const point& ccB = meshB.cellCentres()[cellBI];
156
157 forAll(cFacesA, cFA)
158 {
159 label faceAI = cFacesA[cFA];
160
161 const face& fA = meshA.faces()[faceAI];
162 const treeBoundBox pyrA = pyrBb(meshA.points(), fA, ccA);
163 if (!pyrA.overlaps(cellBbB))
164 {
165 continue;
166 }
167
168 bool ownA = (meshA.faceOwner()[faceAI] == cellAI);
169
170 label tetBasePtAI = 0;
171
172 const point& tetBasePtA = meshA.points()[fA[tetBasePtAI]];
173
174 for (label tetPtI = 1; tetPtI < fA.size() - 1; tetPtI++)
175 {
176 label facePtAI = (tetPtI + tetBasePtAI) % fA.size();
177 label otherFacePtAI = fA.fcIndex(facePtAI);
178
179 label pt0I = -1;
180 label pt1I = -1;
181
182 if (ownA)
183 {
184 pt0I = fA[facePtAI];
185 pt1I = fA[otherFacePtAI];
186 }
187 else
188 {
189 pt0I = fA[otherFacePtAI];
190 pt1I = fA[facePtAI];
191 }
192
193 const tetPoints tetA
194 (
195 ccA,
196 tetBasePtA,
197 meshA.points()[pt0I],
198 meshA.points()[pt1I]
199 );
200
201 const treeBoundBox tetAbb(tetA.bounds());
202
203 // Loop over tets of cellB
204 forAll(cFacesB, cFB)
205 {
206 label faceBI = cFacesB[cFB];
207
208 const face& fB = meshB.faces()[faceBI];
209 const treeBoundBox pyrB = pyrBb(meshB.points(), fB, ccB);
210 if (!pyrB.overlaps(pyrA))
211 {
212 continue;
213 }
214
215 bool ownB = (meshB.faceOwner()[faceBI] == cellBI);
216
217 label tetBasePtBI = 0;
218
219 const point& tetBasePtB = meshB.points()[fB[tetBasePtBI]];
220
221 for (label tetPtI = 1; tetPtI < fB.size() - 1; tetPtI++)
222 {
223 label facePtBI = (tetPtI + tetBasePtBI) % fB.size();
224 label otherFacePtBI = fB.fcIndex(facePtBI);
225
226 label pt0I = -1;
227 label pt1I = -1;
228
229 if (ownB)
230 {
231 pt0I = fB[facePtBI];
232 pt1I = fB[otherFacePtBI];
233 }
234 else
235 {
236 pt0I = fB[otherFacePtBI];
237 pt1I = fB[facePtBI];
238 }
239
240 const tetPoints tetB
241 (
242 ccB,
243 tetBasePtB,
244 meshB.points()[pt0I],
245 meshB.points()[pt1I]
246 );
247
248 const treeBoundBox tetBbb(tetB.bounds());
249
250 if (!tetBbb.overlaps(tetAbb))
251 {
252 continue;
253 }
254
255 if (combineTetsOp(tetA, tetB))
256 {
257 return;
258 }
259 }
260 }
261 }
262 }
263}
264
265
266// ************************************************************************* //
label n
A cell is defined as a list of faces with extra functionality.
Definition cell.H:56
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Cell-face mesh analysis engine.
Tet point storage. Default constructable (tetrahedron is not).
Definition tetrahedron.H:85
FixedList< tetPoints, 200 > tetIntersectionList
void sliceWithPlane(const plane &pl, AboveTetOp &aboveOp, BelowTetOp &belowOp) const
Decompose tet into tets above and below plane.
Standard boundBox with extra functionality for use in octree.
tetrahedron< point, const point & > tetPointRef
A tetrahedron using referred points.
Definition tetrahedron.H:72
dimensionedScalar sqrt(const dimensionedScalar &ds)
vector point
Point is a vector.
Definition point.H:37
Vector< scalar > vector
Definition vector.H:57
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299