Commit 8f6c2057eeb0eb428641e9cd53a7f437139dbdfb

Authored by Jiaming Guo
1 parent 4bb615eb

fixed index marking bugs after network subdivided

Showing 2 changed files with 110 additions and 24 deletions   Show diff stats
@@ -67,7 +67,7 @@ namespace stim { @@ -67,7 +67,7 @@ namespace stim {
67 #ifdef __CUDACC__ 67 #ifdef __CUDACC__
68 // for sphere 68 // for sphere
69 template <typename T> 69 template <typename T>
70 - __global__ void inside_sphere(const stim::sphere<T> *V, size_t num, T Z,size_t *R, T *S, unsigned char *ptr, int x, int y, int z) { 70 + __global__ void inside_sphere(const stim::sphere<T> *V, size_t num, T Z,size_t *R, T *S, unsigned char *ptr, int x, int y, int z, T std = 1.0f) {
71 71
72 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; 72 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x;
73 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; 73 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y;
@@ -93,11 +93,16 @@ namespace stim { @@ -93,11 +93,16 @@ namespace stim {
93 } 93 }
94 if (distance <= V[idx].r) 94 if (distance <= V[idx].r)
95 ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255; 95 ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255;
  96 + else {
  97 + T g = gaussianFunction(std::pow(distance - V[idx].r, 2), std);
  98 + if(g > 0.1f)
  99 + ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255;
  100 + }
96 } 101 }
97 102
98 // for cone 103 // for cone
99 template <typename T> 104 template <typename T>
100 - __global__ void inside_cone(const stim::cone<T> *E, size_t num, T Z, size_t *R, T *S, unsigned char *ptr, int x, int y, int z) { 105 + __global__ void inside_cone(const stim::cone<T> *E, size_t num, T Z, size_t *R, T *S, unsigned char *ptr, int x, int y, int z, T std = 1.0f) {
101 106
102 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; 107 unsigned ix = blockDim.x * blockIdx.x + threadIdx.x;
103 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; 108 unsigned iy = blockDim.y * blockIdx.y + threadIdx.y;
@@ -129,6 +134,11 @@ namespace stim { @@ -129,6 +134,11 @@ namespace stim {
129 } 134 }
130 if (distance <= rr) 135 if (distance <= rr)
131 ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255; 136 ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255;
  137 + else {
  138 + T g = gaussianFunction(std::pow(distance - rr, 2), std);
  139 + if (g > 0.1f)
  140 + ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255;
  141 + }
132 } 142 }
133 143
134 // for source bus 144 // for source bus
@@ -252,7 +262,7 @@ namespace stim { @@ -252,7 +262,7 @@ namespace stim {
252 262
253 bool set = false; // flag indicates the pressure has been set 263 bool set = false; // flag indicates the pressure has been set
254 std::vector<T> P; // initial pressure 264 std::vector<T> P; // initial pressure
255 - std::vector<T> v; // velocity 265 + std::vector<T> v; // average velocity along each edge
256 std::vector<typename stim::vec3<T> > main_feeder; // inlet/outlet main feeder 266 std::vector<typename stim::vec3<T> > main_feeder; // inlet/outlet main feeder
257 std::vector<unsigned> pendant_vertex; 267 std::vector<unsigned> pendant_vertex;
258 std::vector<typename stim::triple<unsigned, unsigned, T> > input; // first one store which vertex, second one stores which edge, third one stores in/out volume flow rate of that vertex 268 std::vector<typename stim::triple<unsigned, unsigned, T> > input; // first one store which vertex, second one stores which edge, third one stores in/out volume flow rate of that vertex
@@ -350,12 +360,22 @@ namespace stim { @@ -350,12 +360,22 @@ namespace stim {
350 return E[tmp_e].r(tmp_v); 360 return E[tmp_e].r(tmp_v);
351 } 361 }
352 362
353 - // get the radius of index j of edge i 363 + // get the radius of point j on edge i
354 T get_radius(unsigned i, unsigned j) { 364 T get_radius(unsigned i, unsigned j) {
355 return E[i].r(j); 365 return E[i].r(j);
356 } 366 }
357 367
358 - // get the pendant vertices 368 + // back up vertices
  369 + std::vector<stim::vec3<T> > back_vertex() {
  370 + std::vector<stim::vec3<T> > result;
  371 +
  372 + for (unsigned i = 0; i < num_vertex; i++)
  373 + result.push_back(stim::vec3<T>(V[i][0], V[i][1], V[i][2]));
  374 +
  375 + return result;
  376 + }
  377 +
  378 + // get pendant vertices
359 std::vector<unsigned> get_pendant_vertex() { 379 std::vector<unsigned> get_pendant_vertex() {
360 std::vector<unsigned> result; 380 std::vector<unsigned> result;
361 int count = 0; 381 int count = 0;
@@ -851,7 +871,7 @@ namespace stim { @@ -851,7 +871,7 @@ namespace stim {
851 } 871 }
852 else 872 else
853 glColor3f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255); 873 glColor3f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255);
854 - 874 +
855 for (unsigned j = 0; j < E[i].size() - 1; j++) { // for every point on the edge 875 for (unsigned j = 0; j < E[i].size() - 1; j++) { // for every point on the edge
856 center1 = E[i][j]; 876 center1 = E[i][j];
857 center2 = E[i][j + 1]; 877 center2 = E[i][j + 1];
@@ -1532,13 +1552,13 @@ namespace stim { @@ -1532,13 +1552,13 @@ namespace stim {
1532 } 1552 }
1533 1553
1534 // mark the vertex 1554 // mark the vertex
1535 - void mark_vertex(T scale = 1.0f) { 1555 + void mark_vertex(std::vector<stim::vec3<T> > vertex, T scale = 1.0f) {
1536 1556
1537 glColor3f(0.0f, 0.0f, 0.0f); 1557 glColor3f(0.0f, 0.0f, 0.0f);
1538 - for (unsigned i = 0; i < num_vertex; i++) {  
1539 - glRasterPos3f(V[i][0], V[i][1] + get_radius(i) * scale, V[i][2]); 1558 + for (unsigned i = 0; i < vertex.size(); i++) {
  1559 + glRasterPos3f(vertex[i][0], vertex[i][1] + get_radius(i) * scale, vertex[i][2]); // place position
1540 std::stringstream ss; 1560 std::stringstream ss;
1541 - ss << i; 1561 + ss << i; // store index value
1542 glutBitmapString(GLUT_BITMAP_HELVETICA_18, (const unsigned char*)(ss.str().c_str())); 1562 glutBitmapString(GLUT_BITMAP_HELVETICA_18, (const unsigned char*)(ss.str().c_str()));
1543 } 1563 }
1544 } 1564 }
@@ -2877,7 +2897,18 @@ namespace stim { @@ -2877,7 +2897,18 @@ namespace stim {
2877 f_file.close(); 2897 f_file.close();
2878 } 2898 }
2879 2899
2880 - /// Calculate the inverse of A and store the result in C 2900 + /// check whether current network needs to be subdivided
  2901 + bool check_subdivision() {
  2902 +
  2903 + for (size_t i = 0; i < num_edge; i++) {
  2904 + if (E[i].size() > 2) {
  2905 + return true;
  2906 + }
  2907 + }
  2908 + return false;
  2909 + }
  2910 +
  2911 + /// calculate the inverse of A and store the result in C
2881 void inversion(T** A, int order, T* C) { 2912 void inversion(T** A, int order, T* C) {
2882 2913
2883 #ifdef __CUDACC__ 2914 #ifdef __CUDACC__
@@ -2970,6 +3001,15 @@ namespace stim { @@ -2970,6 +3001,15 @@ namespace stim {
2970 free(minor); 3001 free(minor);
2971 #endif 3002 #endif
2972 } 3003 }
  3004 +
  3005 + /// arithmetic
  3006 + // assignment
  3007 + flow<T> & operator= (flow<T> rhs) {
  3008 + E = rhs.E;
  3009 + V = rhs.V;
  3010 +
  3011 + return *this;
  3012 + }
2973 }; 3013 };
2974 } 3014 }
2975 3015
@@ -40,6 +40,7 @@ unsigned num_vertex; // number of vertex in the network @@ -40,6 +40,7 @@ unsigned num_vertex; // number of vertex in the network
40 std::vector<unsigned> pendant_vertex; // list of pendant vertex index in GT 40 std::vector<unsigned> pendant_vertex; // list of pendant vertex index in GT
41 std::vector<std::string> menu_option = { "simulation", "build inlet/outlet", "manufacture", "adjustment" }; 41 std::vector<std::string> menu_option = { "simulation", "build inlet/outlet", "manufacture", "adjustment" };
42 stim::flow<float> flow; // flow object 42 stim::flow<float> flow; // flow object
  43 +stim::flow<float> backup; // flow backup
43 float move_pace; // camera moving parameter 44 float move_pace; // camera moving parameter
44 float u; // viscosity 45 float u; // viscosity
45 float rou; // density 46 float rou; // density
@@ -79,7 +80,7 @@ int mouse_x; // window x-coordinate @@ -79,7 +80,7 @@ int mouse_x; // window x-coordinate
79 int mouse_y; // window y-coordinate 80 int mouse_y; // window y-coordinate
80 int picked_x; // picked window x-coordinate 81 int picked_x; // picked window x-coordinate
81 int picked_y; // picked window y-coordinate 82 int picked_y; // picked window y-coordinate
82 -bool LTbutton = false; // true means down while false means up 83 +bool LTbutton = false; // true means down while false means up
83 84
84 // simulation parameters 85 // simulation parameters
85 bool render_direction = false; // flag indicates rendering flow direction for one edge 86 bool render_direction = false; // flag indicates rendering flow direction for one edge
@@ -89,8 +90,10 @@ bool to_select_pressure = false; // flag indicates having selected a vertex to m @@ -89,8 +90,10 @@ bool to_select_pressure = false; // flag indicates having selected a vertex to m
89 bool mark_index = true; // flag indicates marking the index near the vertex 90 bool mark_index = true; // flag indicates marking the index near the vertex
90 bool glyph_mode = false; // flag indicates rendering glyph for flow velocity field 91 bool glyph_mode = false; // flag indicates rendering glyph for flow velocity field
91 bool frame_mode = false; // flag indicates rendering filament framing structrues 92 bool frame_mode = false; // flag indicates rendering filament framing structrues
  93 +bool subdivided = false; // flag indicates subdivision status
92 unsigned pressure_index; // the index of vertex that is clicked 94 unsigned pressure_index; // the index of vertex that is clicked
93 unsigned direction_index = UINT_MAX;// the index of edge that is pointed at 95 unsigned direction_index = UINT_MAX;// the index of edge that is pointed at
  96 +std::vector<stim::vec3<float> > back_vertex; // vertex back up for marking indices
94 97
95 // build inlet/outlet parameters 98 // build inlet/outlet parameters
96 bool build_inlet_outlet = false; // flag indicates building inlets and outlets 99 bool build_inlet_outlet = false; // flag indicates building inlets and outlets
@@ -169,6 +172,8 @@ void flow_initialize() { @@ -169,6 +172,8 @@ void flow_initialize() {
169 172
170 flow.set = true; 173 flow.set = true;
171 stim::vec3<float> center = bb.center(); 174 stim::vec3<float> center = bb.center();
  175 + flow.P.clear();
  176 + flow.P.resize(num_vertex, 0); // clear up initialized pressure
172 177
173 for (unsigned i = 0; i < pendant_vertex.size(); i++) { 178 for (unsigned i = 0; i < pendant_vertex.size(); i++) {
174 if (flow.get_vertex(pendant_vertex[i])[0] <= center[0]) 179 if (flow.get_vertex(pendant_vertex[i])[0] <= center[0])
@@ -271,7 +276,7 @@ void glut_render() { @@ -271,7 +276,7 @@ void glut_render() {
271 if (!glyph_mode) { 276 if (!glyph_mode) {
272 flow.glSolidSphere(max_pressure, subdivision, scale); 277 flow.glSolidSphere(max_pressure, subdivision, scale);
273 if (mark_index) 278 if (mark_index)
274 - flow.mark_vertex(scale); 279 + flow.mark_vertex(back_vertex, scale);
275 //flow.glSolidCone(subdivision); 280 //flow.glSolidCone(subdivision);
276 flow.glSolidCylinder(direction_index, color, subdivision, scale); 281 flow.glSolidCylinder(direction_index, color, subdivision, scale);
277 } 282 }
@@ -288,7 +293,7 @@ void glut_render() { @@ -288,7 +293,7 @@ void glut_render() {
288 if (!glyph_mode) { 293 if (!glyph_mode) {
289 flow.glSolidSphere(max_pressure, subdivision, scale); 294 flow.glSolidSphere(max_pressure, subdivision, scale);
290 if (mark_index) { 295 if (mark_index) {
291 - flow.mark_vertex(scale); 296 + flow.mark_vertex(back_vertex, scale);
292 //flow.mark_edge(); 297 //flow.mark_edge();
293 } 298 }
294 //flow.glSolidCone(subdivision); 299 //flow.glSolidCone(subdivision);
@@ -299,7 +304,7 @@ void glut_render() { @@ -299,7 +304,7 @@ void glut_render() {
299 flow.glyph(color, subdivision, scale, frame_mode); 304 flow.glyph(color, subdivision, scale, frame_mode);
300 } 305 }
301 flow.glSolidCuboid(subdivision, manufacture, length); // render bus source 306 flow.glSolidCuboid(subdivision, manufacture, length); // render bus source
302 - if (render_direction) // render the flow direction of the vertex pointed 307 + if (render_direction && !glyph_mode) // render the flow direction of the vertex pointed
303 flow.glSolidCone(direction_index, subdivision, scale); 308 flow.glSolidCone(direction_index, subdivision, scale);
304 } 309 }
305 310
@@ -495,6 +500,7 @@ void glut_menu(int value) { @@ -495,6 +500,7 @@ void glut_menu(int value) {
495 // first time 500 // first time
496 if (!flow.set) { // only first time simulation called "simulation", ^_^ 501 if (!flow.set) { // only first time simulation called "simulation", ^_^
497 get_background(); // get the graph information 502 get_background(); // get the graph information
  503 + back_vertex = flow.back_vertex(); // vertex back up for marking indices
498 flow_initialize(); // initialize flow condition 504 flow_initialize(); // initialize flow condition
499 menu_option[0] = "resimulation"; 505 menu_option[0] = "resimulation";
500 } 506 }
@@ -584,6 +590,7 @@ void glut_passive_motion(int x, int y) { @@ -584,6 +590,7 @@ void glut_passive_motion(int x, int y) {
584 render_direction = false; 590 render_direction = false;
585 direction_index = -1; 591 direction_index = -1;
586 } 592 }
  593 + undo = true;
587 } 594 }
588 595
589 if (mods == GLUT_ACTIVE_SHIFT && picked_connection) { 596 if (mods == GLUT_ACTIVE_SHIFT && picked_connection) {
@@ -888,7 +895,7 @@ void glut_keyboard(unsigned char key, int x, int y) { @@ -888,7 +895,7 @@ void glut_keyboard(unsigned char key, int x, int y) {
888 895
889 // register different keyboard operation 896 // register different keyboard operation
890 switch (key) { 897 switch (key) {
891 - 898 +
892 // saving network flow profile 899 // saving network flow profile
893 case 's': 900 case 's':
894 flow.save_network(); 901 flow.save_network();
@@ -903,7 +910,39 @@ void glut_keyboard(unsigned char key, int x, int y) { @@ -903,7 +910,39 @@ void glut_keyboard(unsigned char key, int x, int y) {
903 flow.saveNwt(filename); 910 flow.saveNwt(filename);
904 break; 911 break;
905 } 912 }
906 - 913 +
  914 + // subdivide current network for more detailed calculation
  915 + case 'd': {
  916 + // subdivide current network due to the limitation of current computation if needed
  917 + if (!subdivided && simulation && !glyph_mode) {
  918 + subdivided = true;
  919 +
  920 + // check whether current network can be subdivided
  921 + if (flow.check_subdivision()) {
  922 + flow.subdivision();
  923 + get_background();
  924 + }
  925 +
  926 + flow_initialize(); // initialize flow condition
  927 + // resimulation
  928 + flow_stable_state(); // main function of solving the linear system
  929 + flow.print_flow();
  930 + undo = true;
  931 + }
  932 + else if (subdivided && simulation && !glyph_mode) {
  933 + subdivided = false;
  934 + flow = backup; // load back up
  935 +
  936 + get_background();
  937 + flow_initialize();
  938 + // resimulation
  939 + flow_stable_state(); // main function of solving the linear system
  940 + flow.print_flow();
  941 + undo = true;
  942 + }
  943 + break;
  944 + }
  945 +
907 // flow vector field visualization, Glyphs 946 // flow vector field visualization, Glyphs
908 case 'f': 947 case 'f':
909 if (glyph_mode && !manufacture && (simulation || build_inlet_outlet)) { 948 if (glyph_mode && !manufacture && (simulation || build_inlet_outlet)) {
@@ -923,7 +962,7 @@ void glut_keyboard(unsigned char key, int x, int y) { @@ -923,7 +962,7 @@ void glut_keyboard(unsigned char key, int x, int y) {
923 } 962 }
924 undo = true; 963 undo = true;
925 break; 964 break;
926 - 965 +
927 // filaments around arrows 966 // filaments around arrows
928 case 'g': 967 case 'g':
929 if (glyph_mode) { 968 if (glyph_mode) {
@@ -932,8 +971,9 @@ void glut_keyboard(unsigned char key, int x, int y) { @@ -932,8 +971,9 @@ void glut_keyboard(unsigned char key, int x, int y) {
932 else 971 else
933 frame_mode = true; 972 frame_mode = true;
934 } 973 }
  974 + undo = true;
935 break; 975 break;
936 - 976 +
937 // open/close index marks 977 // open/close index marks
938 case 'e': 978 case 'e':
939 if (mark_index) 979 if (mark_index)
@@ -1047,12 +1087,18 @@ int main(int argc, char* argv[]) { @@ -1047,12 +1087,18 @@ int main(int argc, char* argv[]) {
1047 } 1087 }
1048 else { // load network from user 1088 else { // load network from user
1049 std::vector<std::string> tmp = stim::parser::split(args.arg(0), '.'); 1089 std::vector<std::string> tmp = stim::parser::split(args.arg(0), '.');
1050 - if ("obj" == tmp[1]) 1090 + if ("obj" == tmp[1]) {
1051 flow.load_obj(args.arg(0)); 1091 flow.load_obj(args.arg(0));
1052 - else if ("nwt" == tmp[1]) // stim network binary format  
1053 - flow.loadNwt(args.arg(0));  
1054 - else if ("swc" == tmp[1])  
1055 - flow.load_swc(args.arg(0)); 1092 + backup.load_obj(args.arg(0));
  1093 + }
  1094 + else if ("nwt" == tmp[1]) { // stim network binary format
  1095 + flow.loadNwt(args.arg(0));
  1096 + backup.loadNwt(args.arg(0));
  1097 + }
  1098 + else if ("swc" == tmp[1]) {
  1099 + flow.load_swc(args.arg(0));
  1100 + backup.load_swc(args.arg(0));
  1101 + }
1056 else { 1102 else {
1057 std::cout << "Invalid file type" << std::endl; 1103 std::cout << "Invalid file type" << std::endl;
1058 std::exit(1); 1104 std::exit(1);