Commit 6765b32bc869d451831577bf296570687ba00e98

Authored by Jiaming Guo
1 parent 9191c39e

add hilbert curve

Showing 1 changed file with 123 additions and 46 deletions   Show diff stats
@@ -61,7 +61,7 @@ namespace stim { @@ -61,7 +61,7 @@ namespace stim {
61 #ifdef __CUDACC__ 61 #ifdef __CUDACC__
62 // for sphere 62 // for sphere
63 template <typename T> 63 template <typename T>
64 - __global__ void inside_sphere(const stim::sphere<T> *V, unsigned num, size_t *R, T *S, unsigned char *ptr, unsigned x, unsigned y, unsigned z) { 64 + __global__ void inside_sphere(const stim::sphere<T> *V, unsigned num, size_t *R, T *S, unsigned char *ptr, int x, int y, int z) {
65 65
66 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; 66 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x;
67 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; 67 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y;
@@ -91,7 +91,7 @@ namespace stim { @@ -91,7 +91,7 @@ namespace stim {
91 91
92 // for cone 92 // for cone
93 template <typename T> 93 template <typename T>
94 - __global__ void inside_cone(const stim::cone<T> *E, unsigned num, size_t *R, T *S, unsigned char *ptr, unsigned x, unsigned y, unsigned z) { 94 + __global__ void inside_cone(const stim::cone<T> *E, unsigned num, size_t *R, T *S, unsigned char *ptr, int x, int y, int z) {
95 95
96 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; 96 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x;
97 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; 97 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y;
@@ -127,7 +127,7 @@ namespace stim { @@ -127,7 +127,7 @@ namespace stim {
127 127
128 // for source bus 128 // for source bus
129 template <typename T> 129 template <typename T>
130 - __global__ void inside_cuboid(const stim::cuboid<T> *B, unsigned num, size_t *R, T *S, unsigned char *ptr, unsigned x, unsigned y, unsigned z) { 130 + __global__ void inside_cuboid(const stim::cuboid<T> *B, unsigned num, size_t *R, T *S, unsigned char *ptr, int x, int y, int z) {
131 131
132 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; 132 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x;
133 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; 133 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y;
@@ -586,17 +586,6 @@ namespace stim { @@ -586,17 +586,6 @@ namespace stim {
586 } 586 }
587 } 587 }
588 588
589 - void draw_hilbert_curve(unsigned i, T *c, int order, T l, T d, bool upper, int feeder, bool invert) {  
590 -  
591 - T fragment = (d - l) / ((std::pow(4, order) - 1) / (std::pow(2, order) - 1) - 1); // the length of the opening of cup  
592 - T dl = fragment / (std::pow(2, order) - 1); // unit cup length  
593 -  
594 - if (upper)  
595 - hilbert_curve(i, c, order, dl, feeder, invert, DOWN);  
596 - else  
597 - hilbert_curve(i, c, order, dl, feeder, invert, UP);  
598 - }  
599 -  
600 /// render function 589 /// render function
601 // find two envelope caps for two spheres 590 // find two envelope caps for two spheres
602 // @param cp1, cp2: list of points on the cap 591 // @param cp1, cp2: list of points on the cap
@@ -1071,7 +1060,7 @@ namespace stim { @@ -1071,7 +1060,7 @@ namespace stim {
1071 1060
1072 /// build main feeder connection 1061 /// build main feeder connection
1073 // set up main feeder and main port of both input and output 1062 // set up main feeder and main port of both input and output
1074 - void set_main_feeder(T border = 200.0f) { 1063 + void set_main_feeder(T border = 400.0f) {
1075 1064
1076 // 0 means outgoing while 1 means incoming 1065 // 0 means outgoing while 1 means incoming
1077 stim::vec3<T> inlet_main_feeder; 1066 stim::vec3<T> inlet_main_feeder;
@@ -1242,11 +1231,62 @@ namespace stim { @@ -1242,11 +1231,62 @@ namespace stim {
1242 inlet[i].V.push_back(tmp_v); 1231 inlet[i].V.push_back(tmp_v);
1243 inlet[i].l = new_l; 1232 inlet[i].l = new_l;
1244 1233
1245 - draw_hilbert_curve(i, &tmp_v[0], order, origin_l, desire_l, upper, 1, invert);  
1246 - if (tmp_v[0] != mid_v[0])  
1247 - inlet[i].V.push_back(mid_v);  
1248 - inlet[i].V.push_back(bus_v);  
1249 - std::reverse(inlet[i].V.begin(), inlet[i].V.end()); 1234 + if (desire_l - origin_l < 2 * radii) { // do not need to use hilbert curve, just increase the length by draging out
  1235 + T d = new_l - inlet[i].l;
  1236 + stim::vec3<T> corner = stim::vec3<T>(tmp_v[0], tmp_v[1] + d / 2.0f * (tmp_v[1] > main_feeder[0][1] ? 1 : -1), tmp_v[2]);
  1237 + inlet[i].V.push_back(corner);
  1238 + corner = stim::vec3<T>(mid_v[0], mid_v[1] + d / 2.0f * (tmp_v[1] > main_feeder[0][1] ? 1 : -1), mid_v[2]);
  1239 + inlet[i].V.push_back(corner);
  1240 + inlet[i].V.push_back(bus_v);
  1241 + }
  1242 + else {
  1243 + T fragment = (desire_l - origin_l) / ((std::pow(4, order) - 1) / (std::pow(2, order) - 1) - 1); // the length of the opening of cup
  1244 + T dl = fragment / (std::pow(2, order) - 1); // unit cup length
  1245 +
  1246 + if (dl > 2 * radii) { // if the radii is feasible
  1247 + if (upper)
  1248 + hilbert_curve(i, &tmp_v[0], order, dl, 1, invert, DOWN);
  1249 + else
  1250 + hilbert_curve(i, &tmp_v[0], order, dl, 1, invert, UP);
  1251 +
  1252 + if (tmp_v[0] != mid_v[0])
  1253 + inlet[i].V.push_back(mid_v);
  1254 + inlet[i].V.push_back(bus_v);
  1255 + }
  1256 + else { // if the radii is not feasible
  1257 + int count = 1;
  1258 + while (dl <= 2 * radii) {
  1259 + dl = origin_l / (std::pow(2, order - count) - 1);
  1260 + count++;
  1261 + }
  1262 + count--;
  1263 +
  1264 + if (upper)
  1265 + hilbert_curve(i, &tmp_v[0], order - count, dl, 1, invert, DOWN);
  1266 + else
  1267 + hilbert_curve(i, &tmp_v[0], order - count, dl, 1, invert, UP);
  1268 +
  1269 + desire_l -= origin_l * ((std::pow(4, order - count) - 1) / (std::pow(2, order - count) - 1));
  1270 + origin_l = (bus_v - mid_v).len();
  1271 + desire_l += origin_l;
  1272 +
  1273 + find_hilbert_order(origin_l, desire_l, order);
  1274 +
  1275 + fragment = (desire_l - origin_l) / ((std::pow(4, order) - 1) / (std::pow(2, order) - 1) - 1);
  1276 + dl = fragment / (std::pow(2, order) - 1);
  1277 + if (dl < 2 * radii)
  1278 + std::cout << "infeasible connection between inlets!" << std::endl;
  1279 +
  1280 + if (upper)
  1281 + hilbert_curve(i, &tmp_v[0], order, dl, 1, !invert, RIGHT);
  1282 + else
  1283 + hilbert_curve(i, &tmp_v[0], order, dl, 1, !invert, RIGHT);
  1284 +
  1285 + if (tmp_v[1] != bus_v[1])
  1286 + inlet[i].V.push_back(bus_v);
  1287 + }
  1288 + }
  1289 + std::reverse(inlet[i].V.begin(), inlet[i].V.end()); // from bus to pendant vertex
1250 } 1290 }
1251 } 1291 }
1252 1292
@@ -1265,7 +1305,7 @@ namespace stim { @@ -1265,7 +1305,7 @@ namespace stim {
1265 for (unsigned i = 0; i < outlet.size(); i++) { 1305 for (unsigned i = 0; i < outlet.size(); i++) {
1266 if (i != outlet_index) { 1306 if (i != outlet_index) {
1267 new_l = (new_pressure[outlet[i].v[0]] - source_pressure) * ((float)stim::PI * std::pow(radii, 4)) / (8 * viscosity * outlet[i].Q); 1307 new_l = (new_pressure[outlet[i].v[0]] - source_pressure) * ((float)stim::PI * std::pow(radii, 4)) / (8 * viscosity * outlet[i].Q);
1268 - 1308 +
1269 if (outlet[i].V[2][1] > main_feeder[1][1]) { 1309 if (outlet[i].V[2][1] > main_feeder[1][1]) {
1270 upper = true; 1310 upper = true;
1271 invert = true; 1311 invert = true;
@@ -1286,10 +1326,61 @@ namespace stim { @@ -1286,10 +1326,61 @@ namespace stim {
1286 outlet[i].V.push_back(tmp_v); 1326 outlet[i].V.push_back(tmp_v);
1287 outlet[i].l = new_l; 1327 outlet[i].l = new_l;
1288 1328
1289 - draw_hilbert_curve(i, &tmp_v[0], order, origin_l, desire_l, upper, 0, invert);  
1290 - if (tmp_v[0] != mid_v[0])  
1291 - outlet[i].V.push_back(mid_v);  
1292 - outlet[i].V.push_back(bus_v); 1329 + if (desire_l - origin_l < 2 * radii) { // do not need to use hilbert curve, just increase the length by draging out
  1330 + T d = new_l - outlet[i].l;
  1331 + stim::vec3<T> corner = stim::vec3<T>(tmp_v[0], tmp_v[1] + d / 2.0f * (tmp_v[1] > main_feeder[0][1] ? 1 : -1), tmp_v[2]);
  1332 + outlet[i].V.push_back(corner);
  1333 + corner = stim::vec3<T>(mid_v[0], mid_v[1] + d / 2.0f * (tmp_v[1] > main_feeder[0][1] ? 1 : -1), mid_v[2]);
  1334 + outlet[i].V.push_back(corner);
  1335 + outlet[i].V.push_back(bus_v);
  1336 + }
  1337 + else {
  1338 + T fragment = (desire_l - origin_l) / ((std::pow(4, order) - 1) / (std::pow(2, order) - 1) - 1); // the length of the opening of cup
  1339 + T dl = fragment / (std::pow(2, order) - 1); // unit cup length
  1340 +
  1341 + if (dl > 2 * radii) { // if the radii is feasible
  1342 + if (upper)
  1343 + hilbert_curve(i, &tmp_v[0], order, dl, 0, invert, DOWN);
  1344 + else
  1345 + hilbert_curve(i, &tmp_v[0], order, dl, 0, invert, UP);
  1346 +
  1347 + if (tmp_v[0] != mid_v[0])
  1348 + outlet[i].V.push_back(mid_v);
  1349 + outlet[i].V.push_back(bus_v);
  1350 + }
  1351 + else { // if the radii is not feasible
  1352 + int count = 1;
  1353 + while (dl <= 2 * radii) {
  1354 + dl = origin_l / (std::pow(2, order - count) - 1);
  1355 + count++;
  1356 + }
  1357 + count--;
  1358 +
  1359 + if (upper)
  1360 + hilbert_curve(i, &tmp_v[0], order - count, dl, 0, invert, DOWN);
  1361 + else
  1362 + hilbert_curve(i, &tmp_v[0], order - count, dl, 0, invert, UP);
  1363 +
  1364 + desire_l -= origin_l * ((std::pow(4, order - count) - 1) / (std::pow(2, order - count) - 1));
  1365 + origin_l = (bus_v - mid_v).len();
  1366 + desire_l += origin_l;
  1367 +
  1368 + find_hilbert_order(origin_l, desire_l, order);
  1369 +
  1370 + fragment = (desire_l - origin_l) / ((std::pow(4, order) - 1) / (std::pow(2, order) - 1) - 1);
  1371 + dl = fragment / (std::pow(2, order) - 1);
  1372 + if (dl < 2 * radii)
  1373 + std::cout << "infeasible connection between outlets!" << std::endl;
  1374 +
  1375 + if (upper)
  1376 + hilbert_curve(i, &tmp_v[0], order, dl, 0, !invert, LEFT);
  1377 + else
  1378 + hilbert_curve(i, &tmp_v[0], order, dl, 0, !invert, LEFT);
  1379 +
  1380 + if (tmp_v[1] != bus_v[1])
  1381 + outlet[i].V.push_back(bus_v);
  1382 + }
  1383 + }
1293 std::reverse(outlet[i].V.begin(), outlet[i].V.end()); 1384 std::reverse(outlet[i].V.begin(), outlet[i].V.end());
1294 } 1385 }
1295 } 1386 }
@@ -1365,31 +1456,17 @@ namespace stim { @@ -1365,31 +1456,17 @@ namespace stim {
1365 1456
1366 // secondly push back outside connection 1457 // secondly push back outside connection
1367 for (unsigned i = 0; i < inlet.size(); i++) { 1458 for (unsigned i = 0; i < inlet.size(); i++) {
1368 - if (inlet[i].V.size() == 3) {  
1369 - new_sphere.c = inlet[i].V[1]; 1459 + for (unsigned j = 1; j < inlet[i].V.size() - 1; j++) {
  1460 + new_sphere.c = inlet[i].V[j];
1370 new_sphere.r = inlet[i].r; 1461 new_sphere.r = inlet[i].r;
1371 A.push_back(new_sphere); 1462 A.push_back(new_sphere);
1372 } 1463 }
1373 - else {  
1374 - new_sphere.c = inlet[i].V[1];  
1375 - new_sphere.r = inlet[i].r;  
1376 - A.push_back(new_sphere);  
1377 - new_sphere.c = inlet[i].V[2];  
1378 - A.push_back(new_sphere);  
1379 - }  
1380 } 1464 }
1381 for (unsigned i = 0; i < outlet.size(); i++) { 1465 for (unsigned i = 0; i < outlet.size(); i++) {
1382 - if (outlet[i].V.size() == 3) {  
1383 - new_sphere.c = outlet[i].V[1];  
1384 - new_sphere.r = outlet[i].r;  
1385 - A.push_back(new_sphere);  
1386 - }  
1387 - else {  
1388 - new_sphere.c = outlet[i].V[1]; 1466 + for (unsigned j = 1; j < outlet[i].V.size() - 1; j++) {
  1467 + new_sphere.c = outlet[i].V[j];
1389 new_sphere.r = outlet[i].r; 1468 new_sphere.r = outlet[i].r;
1390 A.push_back(new_sphere); 1469 A.push_back(new_sphere);
1391 - new_sphere.c = outlet[i].V[2];  
1392 - A.push_back(new_sphere);  
1393 } 1470 }
1394 } 1471 }
1395 1472
@@ -1491,9 +1568,9 @@ namespace stim { @@ -1491,9 +1568,9 @@ namespace stim {
1491 unsigned p = 0; // percentage of progress 1568 unsigned p = 0; // percentage of progress
1492 for (unsigned i = 0; i < size_z; i++) { 1569 for (unsigned i = 0; i < size_z; i++) {
1493 1570
1494 - unsigned x = 0 - (unsigned)Xl; // translate whole network(including inlet/outlet) to origin  
1495 - unsigned y = 0 - (unsigned)Yb;  
1496 - unsigned z = i + (unsigned)center[2]; // box symmetric along z-axis 1571 + int x = 0 - (int)Xl; // translate whole network(including inlet/outlet) to origin
  1572 + int y = 0 - (int)Yb;
  1573 + int z = i + (int)center[2]; // box symmetric along z-axis
1497 // allocate image slice memory 1574 // allocate image slice memory
1498 unsigned char* d_ptr; 1575 unsigned char* d_ptr;
1499 unsigned char* ptr = (unsigned char*)malloc(num * sizeof(unsigned char)); 1576 unsigned char* ptr = (unsigned char*)malloc(num * sizeof(unsigned char));