1#include "TetrahedronSet.h"
6#include <thrust/sort.h>
10 template<typename TDataType>
11 TetrahedronSet<TDataType>::TetrahedronSet()
12 : TriangleSet<TDataType>()
17 template<typename TDataType>
18 TetrahedronSet<TDataType>::~TetrahedronSet()
22 template<typename TDataType>
23 void TetrahedronSet<TDataType>::setTetrahedrons(std::vector<Tetrahedron>& tetrahedrons)
25 std::vector<Triangle> triangles;
27 mTethedrons.resize(tetrahedrons.size());
28 mTethedrons.assign(tetrahedrons);
30 this->updateTriangles();
33 template<typename TDataType>
34 void TetrahedronSet<TDataType>::setTetrahedrons(DArray<Tetrahedron>& tetrahedrons)
36 if (tetrahedrons.size() != mTethedrons.size())
38 mTethedrons.resize(tetrahedrons.size());
41 mTethedrons.assign(tetrahedrons);
43 this->updateTriangles();
46 template<typename TDataType>
47 void TetrahedronSet<TDataType>::loadTetFile(std::string filename)
49 std::string filename_node = filename; filename_node.append(".node");
50 std::string filename_ele = filename; filename_ele.append(".ele");
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";
60 std::getline(infile_node, line);
61 std::stringstream ss_node(line);
65 std::vector<Coord> nodes;
66 for (int i = 0; i < node_num; i++)
68 std::getline(infile_node, line);
69 std::stringstream data(line);
72 data >> id >> v[0] >> v[1] >> v[2];
77 std::getline(infile_ele, line);
78 std::stringstream ss_ele(line);
82 std::vector<Triangle> tris;
83 std::vector<Tetrahedron> tets;
84 for (int i = 0; i < ele_num; i++)
86 std::getline(infile_ele, line);
87 std::stringstream data(line);
90 data >> id >> tet[0] >> tet[1] >> tet[2] >> tet[3];
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]));
103 this->setPoints(nodes);
105 this->setTriangles(tris);
106 this->setTetrahedrons(tets);
109 template<typename Tetrahedron>
110 __global__ void TetSet_CountTets(
111 DArray<uint> counter,
112 DArray<Tetrahedron> tets)
114 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
115 if (tId >= tets.size()) return;
117 Tetrahedron t = tets[tId];
119 atomicAdd(&counter[t[0]], 1);
120 atomicAdd(&counter[t[1]], 1);
121 atomicAdd(&counter[t[2]], 1);
122 atomicAdd(&counter[t[3]], 1);
125 template<typename Tetrahedron>
126 __global__ void TetSet_SetupTetIds(
127 DArrayList<int> tetIds,
128 DArray<Tetrahedron> tets)
130 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
131 if (tId >= tets.size()) return;
133 Tetrahedron t = tets[tId];
135 tetIds[t[0]].atomicInsert(tId);
136 tetIds[t[1]].atomicInsert(tId);
137 tetIds[t[2]].atomicInsert(tId);
138 tetIds[t[3]].atomicInsert(tId);
141 template<typename TDataType>
142 DArrayList<int>& TetrahedronSet<TDataType>::getVer2Tet()
144 DArray<uint> counter;
145 counter.resize(this->mCoords.size());
148 cuExecute(mTethedrons.size(),
153 mVer2Tet.resize(counter);
156 cuExecute(mTethedrons.size(),
166 template<typename TDataType>
167 void TetrahedronSet<TDataType>::getVolume(DArray<Real>& volume)
176 tIndex = TopologyModule::Triangle(EMPTY, EMPTY, EMPTY);
179 DYN_FUNC Info(int id, TopologyModule::Triangle index) {
185 TopologyModule::Triangle tIndex;
188 template<typename TKey, typename Tetrahedron>
189 __global__ void TetSet_SetupKeys(
192 DArray<Tetrahedron> tets)
194 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
195 if (tId >= tets.size()) return;
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]);
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]));
209 template<typename TKey>
210 __global__ void TetSet_CountTriangleNumber(
214 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
215 if (tId >= keys.size()) return;
217 if (tId == 0 || keys[tId] != keys[tId - 1])
223 template<typename Triangle, typename Tri2Tet, typename TKey>
224 __global__ void TetSet_SetupTriangles(
225 DArray<Triangle> triangles,
226 DArray<Tri2Tet> tri2Tet,
231 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
232 if (tId >= keys.size()) return;
234 int shift = counter[tId];
235 if (tId == 0 || keys[tId] != keys[tId - 1])
237 TKey key = keys[tId];
238 triangles[shift] = tetIds[tId].tIndex;
240 Tri2Tet t2T(EMPTY, EMPTY);
241 t2T[0] = tetIds[tId].tetId;
243 if (tId + 1 < keys.size() && keys[tId + 1] == key)
244 t2T[1] = tetIds[tId + 1].tetId;
246 tri2Tet[shift] = t2T;
250 template<typename TKey>
251 void printTKey(DArray<TKey> keys, int maxLength) {
253 h_keys.resize(keys.size());
256 int psize = min((int)h_keys.size(), maxLength);
257 for (int i = 0; i < psize; i++)
259 printf("%d: %d %d %d \n", i, h_keys[i][0], h_keys[i][1], h_keys[i][2]);
265 void printCount(DArray<int> keys, int maxLength) {
267 h_keys.resize(keys.size());
270 int psize = minimum((int)h_keys.size(), maxLength);
271 for (int i = 0; i < psize; i++)
273 printf("%d: %d \n", i, h_keys[i]);
279 template<typename TDataType>
280 void TetrahedronSet<TDataType>::updateTriangles()
283 uint tetSize = mTethedrons.size();
288 keys.resize(4 * tetSize);
289 tetIds.resize(4 * tetSize);
297 thrust::sort_by_key(thrust::device, keys.begin(), keys.begin() + keys.size(), tetIds.begin());
300 counter.resize(4 * tetSize);
302 cuExecute(keys.size(),
303 TetSet_CountTriangleNumber,
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());
310 mTri2Tet.resize(triNum);
312 auto& pTri = this->getTriangles();
314 cuExecute(keys.size(),
315 TetSet_SetupTriangles,
330 template<typename TDataType>
331 void TetrahedronSet<TDataType>::copyFrom(TetrahedronSet<TDataType>& tetSet)
333 mTethedrons.resize(tetSet.mTethedrons.size());
334 mTethedrons.assign(tetSet.mTethedrons);
336 mTri2Tet.resize(tetSet.mTri2Tet.size());
337 mTri2Tet.assign(tetSet.mTri2Tet);
339 mVer2Tet.assign(tetSet.mVer2Tet);
341 TriangleSet<TDataType>::copyFrom(tetSet);
344 template<typename TDataType>
345 bool TetrahedronSet<TDataType>::isEmpty()
347 return mTethedrons.size() && TriangleSet<TDataType>::isEmpty();
350 DEFINE_CLASS(TetrahedronSet);