Commit 6765b32bc869d451831577bf296570687ba00e98
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 | 61 | #ifdef __CUDACC__ |
62 | 62 | // for sphere |
63 | 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 | 66 | unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; |
67 | 67 | unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; |
... | ... | @@ -91,7 +91,7 @@ namespace stim { |
91 | 91 | |
92 | 92 | // for cone |
93 | 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 | 96 | unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; |
97 | 97 | unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; |
... | ... | @@ -127,7 +127,7 @@ namespace stim { |
127 | 127 | |
128 | 128 | // for source bus |
129 | 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 | 132 | unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; |
133 | 133 | unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; |
... | ... | @@ -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 | 589 | /// render function |
601 | 590 | // find two envelope caps for two spheres |
602 | 591 | // @param cp1, cp2: list of points on the cap |
... | ... | @@ -1071,7 +1060,7 @@ namespace stim { |
1071 | 1060 | |
1072 | 1061 | /// build main feeder connection |
1073 | 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 | 1065 | // 0 means outgoing while 1 means incoming |
1077 | 1066 | stim::vec3<T> inlet_main_feeder; |
... | ... | @@ -1242,11 +1231,62 @@ namespace stim { |
1242 | 1231 | inlet[i].V.push_back(tmp_v); |
1243 | 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 | 1305 | for (unsigned i = 0; i < outlet.size(); i++) { |
1266 | 1306 | if (i != outlet_index) { |
1267 | 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 | 1309 | if (outlet[i].V[2][1] > main_feeder[1][1]) { |
1270 | 1310 | upper = true; |
1271 | 1311 | invert = true; |
... | ... | @@ -1286,10 +1326,61 @@ namespace stim { |
1286 | 1326 | outlet[i].V.push_back(tmp_v); |
1287 | 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 | 1384 | std::reverse(outlet[i].V.begin(), outlet[i].V.end()); |
1294 | 1385 | } |
1295 | 1386 | } |
... | ... | @@ -1365,31 +1456,17 @@ namespace stim { |
1365 | 1456 | |
1366 | 1457 | // secondly push back outside connection |
1367 | 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 | 1461 | new_sphere.r = inlet[i].r; |
1371 | 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 | 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 | 1468 | new_sphere.r = outlet[i].r; |
1390 | 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 | 1568 | unsigned p = 0; // percentage of progress |
1492 | 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 | 1574 | // allocate image slice memory |
1498 | 1575 | unsigned char* d_ptr; |
1499 | 1576 | unsigned char* ptr = (unsigned char*)malloc(num * sizeof(unsigned char)); | ... | ... |