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,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)); |