VirtualFluids 0.2.0
Parallel CFD LBM Solver
Loading...
Searching...
No Matches
TriangleNeighborFinder.cpp
Go to the documentation of this file.
1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
15//
16// This file is part of VirtualFluids. VirtualFluids is free software: you can
17// redistribute it and/or modify it under the terms of the GNU General Public
18// License as published by the Free Software Foundation, either version 3 of
19// the License, or (at your option) any later version.
20//
21// VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
22// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24// for more details.
25//
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
28//
33//=======================================================================================
35#include <omp.h>
36
39
40namespace vf::gpu {
41
42int compare2DArrayAccordingToXYZ(const void *pa, const void *pb) {
43
44 real *a = *((real **)pa);
45 real *b = *((real **)pb);
46
47 //compare X
48 if (a[IDS::x] < b[IDS::x]) return -1;
49 else if (a[IDS::x] > b[IDS::x]) return +1;
50 //compare Y
51 else if (a[IDS::y] < b[IDS::y]) return -1;
52 else if (a[IDS::y] > b[IDS::y]) return +1;
53 //compare Z
54 else if (a[IDS::z] < b[IDS::z]) return -1;
55 else if (a[IDS::z] > b[IDS::z]) return +1;
56 //compare Index
57 else if (a[IDS::vertexID] < b[IDS::vertexID]) return -1;
58 else if (a[IDS::vertexID] > b[IDS::vertexID]) return +1;
59
60 return 0;
61}
62
63int compare2DArrayAccordingToIndex(const void *pa, const void *pb) {
64
65 real *a = *((real **)pa);
66 real *b = *((real **)pb);
67
68 if (a[IDS::vertexID] < b[IDS::vertexID]) return -1;
69 else if (a[IDS::vertexID] > b[IDS::vertexID]) return +1;
70 return 0;
71}
72
73TriangleNeighborFinder::TriangleNeighborFinder(Triangle *triangles, int size) : triangles(triangles)
74{
75 numberOfRows = size * DIMENSION;
76
77 this->initalSortedInSpaceWithCoords(triangles, size);
78
80
81 this->fillSortedInSpaceWithFirstVertexAndCoordinateIDs(numberOfRows);
82
83 //copy the array:
84 sortedToTriangles = new real*[numberOfRows];
85 for (int i = 0; i < numberOfRows; i++) {
86 sortedToTriangles[i] = new real[4];
91 }
92
94
95 indicesOfTriangleNeighbors.resize(size);
96
97 this->fillVectorWithIndicesOfTriangleNeighbors();
98}
99
100
101void TriangleNeighborFinder::initalSortedInSpaceWithCoords(Triangle *triangles, int size)
102{
103 sortedInSpace = new real*[numberOfRows];
104
105 int vertexCounter = 0;
106 const int numberOfColumns = 6;
107 for (int i = 0; i < size; i++){
112 sortedInSpace[vertexCounter][IDS::x] = triangles[i].v1.x;
113 sortedInSpace[vertexCounter][IDS::y] = triangles[i].v1.y;
114 sortedInSpace[vertexCounter][IDS::z] = triangles[i].v1.z;
115
121 sortedInSpace[vertexCounter][IDS::x] = triangles[i].v2.x;
122 sortedInSpace[vertexCounter][IDS::y] = triangles[i].v2.y;
123 sortedInSpace[vertexCounter][IDS::z] = triangles[i].v2.z;
124
130 sortedInSpace[vertexCounter][IDS::x] = triangles[i].v3.x;
131 sortedInSpace[vertexCounter][IDS::y] = triangles[i].v3.y;
132 sortedInSpace[vertexCounter][IDS::z] = triangles[i].v3.z;
134 }
135}
136
138{
139 for (int i = 0; i < numberOfRows; i++){
140 delete[] sortedToTriangles[i];
141 delete[] sortedInSpace[i];
142 }
143 delete[] sortedToTriangles;
144 delete[] sortedInSpace;
145}
146
147void TriangleNeighborFinder::fillSortedInSpaceWithFirstVertexAndCoordinateIDs(int numberOfRows)
148{
149 int firstVertexID = 0;
150 int compareID = 0;
151 int coordinateID = 0;
152 int duplicates = 0;
153
154 while (firstVertexID < numberOfRows) {
155 Vertex a = Vertex(sortedInSpace[firstVertexID][IDS::x], sortedInSpace[firstVertexID][IDS::y], sortedInSpace[firstVertexID][IDS::z]);
157 while (a.getEuclideanDistanceTo(b) < 1e-7)
158 {
161 duplicates++;
162
163 compareID++;
164 if (compareID == numberOfRows)
165 break;
167 }
168 firstVertexID += duplicates;
169 duplicates = 0;
170 coordinateID++;
171 }
172}
173
174void TriangleNeighborFinder::fillVectorWithIndicesOfTriangleNeighbors()
175{
176 for (unsigned int triangleID = 0; triangleID < indicesOfTriangleNeighbors.size(); triangleID++){
177
178 Vertex coordinateIDsFromTriangle = getCoordinatesIDfromTriangle(triangleID);
179
180 for (unsigned int vertex = 0; vertex < DIMENSION; vertex++){
181 unsigned int vertexID = triangleID * DIMENSION + vertex;
182 unsigned int firstVertexID = (int)sortedToTriangles[vertexID][IDS::firstVertexID];
183 unsigned int uniqueCoordID = (int)sortedToTriangles[firstVertexID][IDS::uniqueCoordID];
184
185 while (firstVertexID == sortedInSpace[uniqueCoordID][IDS::firstVertexID]){
186 unsigned int jTriangle = findTriangleID(uniqueCoordID);
187
188 uniqueCoordID++;
189 if (uniqueCoordID >= indicesOfTriangleNeighbors.size()*DIMENSION)
190 break;
191 if (jTriangle == triangleID)
192 continue;
193
194 Vertex coordinateIDsFromTriangleNeighbor = getCoordinatesIDfromTriangle(jTriangle);
195
196 if (isTriangleNeighborOfParentTriangle(coordinateIDsFromTriangle, coordinateIDsFromTriangleNeighbor)
197 && isNeighborNotAlreadyInside(triangleID, jTriangle))
199 }
200
201 }
202 }
203}
204
205unsigned int TriangleNeighborFinder::findTriangleID(unsigned int uniqueCoordID)
206{
207 return (int)sortedInSpace[uniqueCoordID][IDS::vertexID] / DIMENSION;
208}
209
210Vertex TriangleNeighborFinder::getCoordinatesIDfromTriangle(int triangleID)
211{
216}
217
218
219bool TriangleNeighborFinder::isTriangleNeighborOfParentTriangle(Vertex v1, Vertex v2)
220{
221 int countSameID = 0;
222 if (v1.x == v2.x)
223 countSameID++;
224 else if (v1.x == v2.y)
225 countSameID++;
226 else if (v1.x == v2.z)
227 countSameID++;
228
229 if (v1.y == v2.x)
230 countSameID++;
231 else if (v1.y == v2.y)
232 countSameID++;
233 else if (v1.y == v2.z)
234 countSameID++;
235
236 if (v1.z == v2.x)
237 countSameID++;
238 else if (v1.z == v2.y)
239 countSameID++;
240 else if (v1.z == v2.z)
241 countSameID++;
242
243 if (countSameID == 2 || countSameID == 3)
244 return true;
245
246 return false;
247}
248
249bool TriangleNeighborFinder::isNeighborNotAlreadyInside(unsigned int iTriangle, unsigned int jTriangle)
250{
251 for (unsigned int i = 0; i < indicesOfTriangleNeighbors[iTriangle].size(); i++){
253 return false;
254 }
255 return true;
256}
257
259{
260 for (unsigned int i = 0; i < indicesOfTriangleNeighbors.size(); i++){
261 int row = i * neighborIndices->DIM;
262 neighborIndices->ptr[row + 0] = neighborIndices->ptr[row + 1] = neighborIndices->ptr[row + 2] = -1;
263 for (unsigned int j = 0; j < indicesOfTriangleNeighbors[i].size(); j++){
264 int index = triangles[i].getCommonEdge(triangles[indicesOfTriangleNeighbors[i][j]]);
265 neighborIndices->ptr[row + index] = indicesOfTriangleNeighbors[i][j];
266 }
267 }
268}
269
271{
272 int j, index, indexNeighbor;
273 //#pragma omp parallel for private(j, row, index, indexNeighbor) shared(neighborAngles->ptr)
274 for (int i = 0; i < (int)indicesOfTriangleNeighbors.size(); i++){
275 geom->triangles[i].alphaAngles[0] = geom->triangles[i].alphaAngles[1] = geom->triangles[i].alphaAngles[2] = 90.0f;
276 for (j = 0; j < (int)indicesOfTriangleNeighbors[i].size(); j++){
278 index = geom->triangles[i].getCommonEdge(geom->triangles[indexNeighbor]);
279 geom->triangles[i].alphaAngles[index] = geom->triangles[i].getHalfAngleBetweenToAdjacentTriangle(geom->triangles[indexNeighbor]);
280 }
281 }
282
283 //for (size_t i = 0; i < neighborAngles->size; i++)
284 //{
285 // int row = i * 3;
286 // printf("triangle : %d\n", i);
287 // for (size_t j = 0; j < 3; j++)
288 // {
289 // printf(" %d ", neighborAngles->ptr[row + j]);
290 // }
291 // printf("\n");
292 //}
293}
294
296{
297 std::vector<int> triangleIDs;
298
301 const int coordinateID = sortedInSpace[uniqueCoordID][IDS::coordinateID];
302 while (coordinateID == sortedInSpace[uniqueCoordID][IDS::coordinateID])
303 {
304 int triangleID = sortedInSpace[uniqueCoordID][IDS::vertexID] / 3;
305 triangleIDs.push_back(triangleID);
306 uniqueCoordID++;
307 if (uniqueCoordID == numberOfRows)
308 break;
309 }
310
311 return triangleIDs;
312}
313
314std::vector< std::vector<Triangle> > TriangleNeighborFinder::getTrianglesPerVertex() const
315{
316 std::vector< std::vector<Triangle> > connected;
317 int uniqueCoordID = 0;
318 while (uniqueCoordID < numberOfRows)
319 {
320 std::vector<Triangle> triangles;
321
322 int nextCoordinateID = this->sortedInSpace[uniqueCoordID][IDS::coordinateID];
323 int currentCoordinateID = this->sortedInSpace[uniqueCoordID][IDS::coordinateID];
325 {
326 const int vertexID = this->sortedInSpace[uniqueCoordID][IDS::vertexID];
327 const int triangleID = vertexID / 3;
328 triangles.push_back(this->triangles[triangleID]);
329
330 uniqueCoordID++;
331 if (uniqueCoordID >= numberOfRows)
332 break;
334 nextCoordinateID = this->sortedInSpace[uniqueCoordID][IDS::coordinateID];
335 }
336 connected.push_back(triangles);
337 }
338 return connected;
339}
340
341
343{
344 printf("VertexID | FirstVertexID | CoordID | UniqueCoordID\n");
345 for (int row = 0; row < numberOfRows; row++) {
347 }
348}
349
351{
352 printf("VertexID | X | Y | Z | FirstVertexID | CoordID | UniqueCoordID\n");
353 for (int row = 0; row < numberOfRows; row++) {
355 }
356}
357
358}
359
std::vector< std::vector< uint > > indicesOfTriangleNeighbors
TriangleNeighborFinder(Triangle *triangles, int size)
void fillWithNeighborAngles(TriangularMesh *geom) const
std::vector< int > getTriangleIDsWithCommonVertex(int vertexID) const
std::vector< std::vector< Triangle > > getTrianglesPerVertex() const
void fillWithNeighborIndices(IntegerPtr2D *indices, Triangle *triangles)
std::shared_ptr< T > SPtr
float real
Definition DataTypes.h:42
#define DIMENSION
Definition global.h:38
int compare2DArrayAccordingToIndex(const void *pa, const void *pb)
int compare2DArrayAccordingToXYZ(const void *pa, const void *pb)
int getCommonEdge(const Triangle &t2) const
Definition Triangle.cpp:249
real getEuclideanDistanceTo(const Vertex &w) const
Definition Vertex.cpp:43