sid::plot* sid::plots::get_plot_at(plot::plot_offset pofs) { plot* pltFirst = this->first(); plot::plot_offset pofsFirst = pltFirst->get_plot_offset(); plot::plot_offset pofsDelta = pofs - pofsFirst; plot* pltRetVal = this->__m_plots[coords_to_index(pofsDelta)]; return pltRetVal; }
//----------------------------------------------------------------------------- void Heightfield::set_altitude(uint32_t x, uint32_t y, float altitude) { const uint32_t adjusted_altitude = (altitude < m_min_altitude) ? m_min_altitude : (altitude > m_max_altitude) ? m_max_altitude : altitude; m_altitudes[coords_to_index(x, y)] = adjusted_altitude; }
//----------------------------------------------------------------------------- float Heightfield::altitude(uint32_t x, uint32_t y) const { return m_altitudes[coords_to_index(x, y)]; }
sid::plot* sid::plots::at(uint index_X, uint index_Z) { return (__m_plots[coords_to_index(index_X, index_Z)]); }
sid::plot* sid::plots::at(const plot::plot_offset& pofs) { return (__m_plots[coords_to_index(pofs.get_x(), pofs.get_z())]); }
//================================================== // simulation //================================================== void simulate(int seed){ ran_seed(seed); int N = 18*512; double radius = 1.0; double L = sqrt(1.02*pi*radius*radius*N); int Npercell = 50; int pbc[] = {1,1}; double epsilon = 180.0; double damp_coeff = 0.3; double kickforce = 20.0; double dt = 1e-1; double t = 0.0; double R = 2*radius; double R2 = R*R; int i, j, k; int *key; int *type = (int*)malloc(sizeof(int)*N); int *neigh = (int*)malloc(sizeof(int)*N); double *rad = (double*)malloc(sizeof(double)*N); double *col = (double*)malloc(sizeof(double)*N); for (i=0; i<N; i++){ type[i] = neigh[i] = rad[i] = 0;} double *x = (double*)malloc(sizeof(double)*2*N); double *v = (double*)malloc(sizeof(double)*2*N); double *f = (double*)malloc(sizeof(double)*2*N); double *w = (double*)malloc(sizeof(double)*2*N); double *o = (double*)malloc(sizeof(double)*2*N); for (i=0; i<2*N; i++){o[i] = x[i] = v[i] = f[i] = w[i] = 0.0;} #ifdef PLOT double time_end = 1e20; #else double time_end = 1e2; #endif #ifdef PLOT plot_init(); plot_clear_screen(); key = plot_render_particles(x, rad, type, N, L,col); #endif //------------------------------------------------- // initialize for (i=0; i<N; i++){ rad[i] = radius; x[2*i+0] = L*ran_ran2(); x[2*i+1] = L*ran_ran2(); v[2*i+0] = 0.0; v[2*i+1] = 0.0; type[i] = BLACK; if (i==0) type[i] = RED; } //------------------------------------------------------- // make boxes for the neighborlist int size[2]; int size_total = 1; for (i=0; i<2; i++){ size[i] = (int)(L / (R)); size_total *= size[i]; } int *count = (int*)malloc(sizeof(int)*2*size_total); int *cells = (int*)malloc(sizeof(int)*2*size_total*Npercell); for (i=0; i<size_total; i++){ for (j=0; j<Npercell; j++) cells[i*Npercell + j] = 0; count[i] = 0; } //========================================================== // where the magic happens //========================================================== int frames = 0; #ifdef FPS struct timespec start; clock_gettime(CLOCK_REALTIME, &start); #endif int STRESS = 1; double T = 0.0; for (t=0.0; t<time_end; t+=dt){ double colmax = 0.0; int index[2]; for (i=0; i<size_total; i++) count[i] = 0; for (i=0; i<N; i++){ col[i] = 0.0; coords_to_index(&x[2*i], size, index, L); int t = index[0] + index[1]*size[0]; cells[t*Npercell+count[t]] = i; count[t]++; } int tt[2]; int tix[2]; int image[2]; double dx[2]; for (i=0; i<N; i++){ f[2*i+0] = 0.0; f[2*i+1] = 0.0; coords_to_index(&x[2*i], size, index, L); for (tt[0]=-1; tt[0]<=1; tt[0]++){ for (tt[1]=-1; tt[1]<=1; tt[1]++){ int goodcell = 1; for (j=0; j<2; j++){ tix[j] = mod_rvec(index[j]+tt[j],size[j]-1,pbc[j],&image[j]); if (pbc[j] < image[j]) goodcell=0; } if (goodcell){ int ind = tix[0] + tix[1]*size[0]; for (j=0; j<count[ind]; j++){ int n = cells[ind*Npercell+j]; double dist = 0.0; for (k=0; k<2; k++){ dx[k] = x[2*n+k] - x[2*i+k]; if (image[k]) dx[k] += L*tt[k]; dist += dx[k]*dx[k]; } //=============================================== // force calculation - hertz if (dist > 1e-10 && dist < R2){ double r0 = R; double l = sqrt(dist); double co = epsilon * (1-l/r0)*(1-l/r0) * (l<r0); for (k=0; k<2; k++){ f[2*i+k] += - dx[k] * co; if (STRESS==1) col[i] += co*co*dx[k]*dx[k];//100*co*dx[k];//sqrt(co*co*dx[k]*dx[k]); } if (STRESS==2) col[i] += dx[1] * co*co*dx[1]; if (STRESS==3) col[i] += dx[0] * co*co*dx[0]; if (STRESS==4) col[i] += dx[1] * co*co*dx[0]; } } } } } //==================================== // damping f[2*i+0] -= damp_coeff*v[2*i+0]; f[2*i+1] -= damp_coeff*v[2*i+1]; //===================================== // noise f[2*i+0] += T*(ran_ran2()-0.5); f[2*i+1] += T*(ran_ran2()-0.5); //===================================== // kick force f[2*i+0] += o[2*i+0]; o[2*i+0] = 0.0; f[2*i+1] += o[2*i+1]; o[2*i+1] = 0.0; //======================= // color norm if (col[i] > colmax) colmax = col[i]; } // now integrate the forces since we have found them for (i=0; i<N;i++){ // Newton-Stomer-Verlet if (key['h'] != 1){ v[2*i+0] += f[2*i+0] * dt; v[2*i+1] += f[2*i+1] * dt; x[2*i+0] += v[2*i+0] * dt; x[2*i+1] += v[2*i+1] * dt; } // boundary conditions for (j=0; j<2; j++){ if (pbc[j] == 1){ if (x[2*i+j] >= L-EPSILON || x[2*i+j] < 0) x[2*i+j] = mymod(x[2*i+j], L); } else { const double restoration = 1.0; if (x[2*i+j] >= L){x[2*i+j] = 2*L-x[2*i+j]; v[2*i+j] *= -restoration;} if (x[2*i+j] < 0) {x[2*i+j] = -x[2*i+j]; v[2*i+j] *= -restoration;} if (x[2*i+j] >= L-EPSILON || x[2*i+j] < 0){x[2*i+j] = mymod(x[2*i+j], L);} } } // just check for errors if (x[2*i+0] >= L || x[2*i+0] < 0.0 || x[2*i+1] >= L || x[2*i+1] < 0.0) printf("out of bounds\n"); //col[i] += v[2*i+0]*v[2*i+0] + v[2*i+1]*v[2*i+1]; if (STRESS == 1) col[i] = col[i]/8; if (STRESS == 2) col[i] = col[i]/16; if (STRESS == 3) col[i] = col[i]/16; if (STRESS == 4) col[i] = col[i]/4; if (STRESS > 1) col[i] = fabs(col[i])+0.5; } #ifdef PLOT const int FRAMESKIP = 1; if (frames % FRAMESKIP == 0){ char filename[100]; sprintf(filename, "screen_%05d.png", frames/FRAMESKIP); plot_clear_screen(); key = plot_render_particles(x, rad, type, N, L,col); #ifdef IMAGES plot_saveimage(filename); #endif } #endif frames++; if (key['1'] == 1) STRESS = 1; if (key['2'] == 1) STRESS = 2; if (key['3'] == 1) STRESS = 3; if (key['4'] == 1) STRESS = 4; if (key['q'] == 1) break; if (key['w'] == 1){ for (i=0; i<N; i++){ if (type[i] == RED) o[2*i+1] = -kickforce; } } if (key['s'] == 1){ for (i=0; i<N; i++){ if (type[i] == RED) o[2*i+1] = kickforce; } } if (key['a'] == 1){ for (i=0; i<N; i++){ if (type[i] == RED) o[2*i+0] = -kickforce; } } if (key['d'] == 1){ for (i=0; i<N; i++){ if (type[i] == RED) o[2*i+0] = kickforce; } } if (key['9'] == 1) T -= 0.01; if (key['0'] == 1) T += 0.01; if (key['8'] == 1) T = 0.0; if (key['o'] == 1) L -= 0.01; if (key['p'] == 1) L += 0.01; } // end of the magic, cleanup //---------------------------------------------- #ifdef FPS struct timespec end; clock_gettime(CLOCK_REALTIME, &end); printf("fps = %f\n", frames/(end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec)/1e9); #endif free(cells); free(count); free(x); free(v); free(f); free(w); free(o); free(neigh); free(rad); free(type); #ifdef PLOT plot_clean(); #endif }