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