PeriDyno 1.0.0
Loading...
Searching...
No Matches
TetrahedronSet.cu
Go to the documentation of this file.
1#include "TetrahedronSet.h"
2#include <fstream>
3#include <iostream>
4#include <sstream>
5
6#include <thrust/sort.h>
7
8namespace dyno
9{
10 template<typename TDataType>
11 TetrahedronSet<TDataType>::TetrahedronSet()
12 : TriangleSet<TDataType>()
13 {
14
15 }
16
17 template<typename TDataType>
18 TetrahedronSet<TDataType>::~TetrahedronSet()
19 {
20 }
21
22 template<typename TDataType>
23 void TetrahedronSet<TDataType>::setTetrahedrons(std::vector<Tetrahedron>& tetrahedrons)
24 {
25 std::vector<Triangle> triangles;
26
27 mTethedrons.resize(tetrahedrons.size());
28 mTethedrons.assign(tetrahedrons);
29
30 this->updateTriangles();
31 }
32
33 template<typename TDataType>
34 void TetrahedronSet<TDataType>::setTetrahedrons(DArray<Tetrahedron>& tetrahedrons)
35 {
36 if (tetrahedrons.size() != mTethedrons.size())
37 {
38 mTethedrons.resize(tetrahedrons.size());
39 }
40
41 mTethedrons.assign(tetrahedrons);
42
43 this->updateTriangles();
44 }
45
46 template<typename TDataType>
47 void TetrahedronSet<TDataType>::loadTetFile(std::string filename)
48 {
49 std::string filename_node = filename; filename_node.append(".node");
50 std::string filename_ele = filename; filename_ele.append(".ele");
51
52 std::ifstream infile_node(filename_node);
53 std::ifstream infile_ele(filename_ele);
54 if (!infile_node || !infile_ele) {
55 std::cerr << "Failed to open the tetrahedron file. Terminating.\n";
56 exit(-1);
57 }
58
59 std::string line;
60 std::getline(infile_node, line);
61 std::stringstream ss_node(line);
62
63 int node_num;
64 ss_node >> node_num;
65 std::vector<Coord> nodes;
66 for (int i = 0; i < node_num; i++)
67 {
68 std::getline(infile_node, line);
69 std::stringstream data(line);
70 int id;
71 Coord v;
72 data >> id >> v[0] >> v[1] >> v[2];
73 nodes.push_back(v);
74 }
75
76
77 std::getline(infile_ele, line);
78 std::stringstream ss_ele(line);
79
80 int ele_num;
81 ss_ele >> ele_num;
82 std::vector<Triangle> tris;
83 std::vector<Tetrahedron> tets;
84 for (int i = 0; i < ele_num; i++)
85 {
86 std::getline(infile_ele, line);
87 std::stringstream data(line);
88 int id;
89 Tetrahedron tet;
90 data >> id >> tet[0] >> tet[1] >> tet[2] >> tet[3];
91 tet[0] -= 0;
92 tet[1] -= 0;
93 tet[2] -= 0;
94 tet[3] -= 0;
95 tets.push_back(tet);
96
97 tris.push_back(Triangle(tet[0], tet[1], tet[2]));
98 tris.push_back(Triangle(tet[0], tet[3], tet[1]));
99 tris.push_back(Triangle(tet[1], tet[3], tet[2]));
100 tris.push_back(Triangle(tet[0], tet[2], tet[3]));
101 }
102
103 this->setPoints(nodes);
104
105 this->setTriangles(tris);
106 this->setTetrahedrons(tets);
107 }
108
109 template<typename Tetrahedron>
110 __global__ void TetSet_CountTets(
111 DArray<uint> counter,
112 DArray<Tetrahedron> tets)
113 {
114 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
115 if (tId >= tets.size()) return;
116
117 Tetrahedron t = tets[tId];
118
119 atomicAdd(&counter[t[0]], 1);
120 atomicAdd(&counter[t[1]], 1);
121 atomicAdd(&counter[t[2]], 1);
122 atomicAdd(&counter[t[3]], 1);
123 }
124
125 template<typename Tetrahedron>
126 __global__ void TetSet_SetupTetIds(
127 DArrayList<int> tetIds,
128 DArray<Tetrahedron> tets)
129 {
130 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
131 if (tId >= tets.size()) return;
132
133 Tetrahedron t = tets[tId];
134
135 tetIds[t[0]].atomicInsert(tId);
136 tetIds[t[1]].atomicInsert(tId);
137 tetIds[t[2]].atomicInsert(tId);
138 tetIds[t[3]].atomicInsert(tId);
139 }
140
141 template<typename TDataType>
142 DArrayList<int>& TetrahedronSet<TDataType>::getVer2Tet()
143 {
144 DArray<uint> counter;
145 counter.resize(this->mCoords.size());
146 counter.reset();
147
148 cuExecute(mTethedrons.size(),
149 TetSet_CountTets,
150 counter,
151 mTethedrons);
152
153 mVer2Tet.resize(counter);
154
155 counter.reset();
156 cuExecute(mTethedrons.size(),
157 TetSet_SetupTetIds,
158 mVer2Tet,
159 mTethedrons);
160
161 counter.clear();
162
163 return mVer2Tet;
164 }
165
166 template<typename TDataType>
167 void TetrahedronSet<TDataType>::getVolume(DArray<Real>& volume)
168 {
169
170 }
171
172 struct Info
173 {
174 DYN_FUNC Info() {
175 tetId = EMPTY;
176 tIndex = TopologyModule::Triangle(EMPTY, EMPTY, EMPTY);
177 }
178
179 DYN_FUNC Info(int id, TopologyModule::Triangle index) {
180 tetId = id;
181 tIndex = index;
182 };
183
184 int tetId;
185 TopologyModule::Triangle tIndex;
186 };
187
188 template<typename TKey, typename Tetrahedron>
189 __global__ void TetSet_SetupKeys(
190 DArray<TKey> keys,
191 DArray<Info> ids,
192 DArray<Tetrahedron> tets)
193 {
194 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
195 if (tId >= tets.size()) return;
196
197 Tetrahedron tet = tets[tId];
198 keys[4 * tId] = TKey(tet[0], tet[1], tet[2]);
199 keys[4 * tId + 1] = TKey(tet[1], tet[2], tet[3]);
200 keys[4 * tId + 2] = TKey(tet[2], tet[3], tet[0]);
201 keys[4 * tId + 3] = TKey(tet[3], tet[0], tet[1]);
202
203 ids[4 * tId] = Info(tId, TopologyModule::Triangle(tet[0], tet[1], tet[2]));
204 ids[4 * tId + 1] = Info(tId, TopologyModule::Triangle(tet[1], tet[2], tet[3]));
205 ids[4 * tId + 2] = Info(tId, TopologyModule::Triangle(tet[2], tet[3], tet[0]));
206 ids[4 * tId + 3] = Info(tId, TopologyModule::Triangle(tet[3], tet[0], tet[1]));
207 }
208
209 template<typename TKey>
210 __global__ void TetSet_CountTriangleNumber(
211 DArray<int> counter,
212 DArray<TKey> keys)
213 {
214 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
215 if (tId >= keys.size()) return;
216
217 if (tId == 0 || keys[tId] != keys[tId - 1])
218 counter[tId] = 1;
219 else
220 counter[tId] = 0;
221 }
222
223 template<typename Triangle, typename Tri2Tet, typename TKey>
224 __global__ void TetSet_SetupTriangles(
225 DArray<Triangle> triangles,
226 DArray<Tri2Tet> tri2Tet,
227 DArray<TKey> keys,
228 DArray<int> counter,
229 DArray<Info> tetIds)
230 {
231 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
232 if (tId >= keys.size()) return;
233
234 int shift = counter[tId];
235 if (tId == 0 || keys[tId] != keys[tId - 1])
236 {
237 TKey key = keys[tId];
238 triangles[shift] = tetIds[tId].tIndex;
239
240 Tri2Tet t2T(EMPTY, EMPTY);
241 t2T[0] = tetIds[tId].tetId;
242
243 if (tId + 1 < keys.size() && keys[tId + 1] == key)
244 t2T[1] = tetIds[tId + 1].tetId;
245
246 tri2Tet[shift] = t2T;
247 }
248 }
249
250 template<typename TKey>
251 void printTKey(DArray<TKey> keys, int maxLength) {
252 CArray<TKey> h_keys;
253 h_keys.resize(keys.size());
254 h_keys.assign(keys);
255
256 int psize = min((int)h_keys.size(), maxLength);
257 for (int i = 0; i < psize; i++)
258 {
259 printf("%d: %d %d %d \n", i, h_keys[i][0], h_keys[i][1], h_keys[i][2]);
260 }
261
262 h_keys.clear();
263 }
264
265 void printCount(DArray<int> keys, int maxLength) {
266 CArray<int> h_keys;
267 h_keys.resize(keys.size());
268 h_keys.assign(keys);
269
270 int psize = minimum((int)h_keys.size(), maxLength);
271 for (int i = 0; i < psize; i++)
272 {
273 printf("%d: %d \n", i, h_keys[i]);
274 }
275
276 h_keys.clear();
277 }
278
279 template<typename TDataType>
280 void TetrahedronSet<TDataType>::updateTriangles()
281 {
282
283 uint tetSize = mTethedrons.size();
284
285 DArray<TKey> keys;
286 DArray<Info> tetIds;
287
288 keys.resize(4 * tetSize);
289 tetIds.resize(4 * tetSize);
290
291 cuExecute(tetSize,
292 TetSet_SetupKeys,
293 keys,
294 tetIds,
295 mTethedrons);
296
297 thrust::sort_by_key(thrust::device, keys.begin(), keys.begin() + keys.size(), tetIds.begin());
298
299 DArray<int> counter;
300 counter.resize(4 * tetSize);
301
302 cuExecute(keys.size(),
303 TetSet_CountTriangleNumber,
304 counter,
305 keys);
306
307 int triNum = thrust::reduce(thrust::device, counter.begin(), counter.begin() + counter.size());
308 thrust::exclusive_scan(thrust::device, counter.begin(), counter.begin() + counter.size(), counter.begin());
309
310 mTri2Tet.resize(triNum);
311
312 auto& pTri = this->getTriangles();
313 pTri.resize(triNum);
314 cuExecute(keys.size(),
315 TetSet_SetupTriangles,
316 pTri,
317 mTri2Tet,
318 keys,
319 counter,
320 tetIds);
321
322 counter.clear();
323 tetIds.clear();
324 keys.clear();
325
326 this->updateEdges();
327 }
328
329
330 template<typename TDataType>
331 void TetrahedronSet<TDataType>::copyFrom(TetrahedronSet<TDataType>& tetSet)
332 {
333 mTethedrons.resize(tetSet.mTethedrons.size());
334 mTethedrons.assign(tetSet.mTethedrons);
335
336 mTri2Tet.resize(tetSet.mTri2Tet.size());
337 mTri2Tet.assign(tetSet.mTri2Tet);
338
339 mVer2Tet.assign(tetSet.mVer2Tet);
340
341 TriangleSet<TDataType>::copyFrom(tetSet);
342 }
343
344 template<typename TDataType>
345 bool TetrahedronSet<TDataType>::isEmpty()
346 {
347 return mTethedrons.size() && TriangleSet<TDataType>::isEmpty();
348 }
349
350 DEFINE_CLASS(TetrahedronSet);
351}