/* * A Simple Fluid Solver Wind by Jos Stam for OpenSim * http://www.dgp.utoronto.ca/people/stam/reality/Research/pub.html * * * Using FFTW v2.0 http://www.fftw.org * */ #include #include #include #include #include #define MAX_THREAD_NUM 36 static rfftwnd_plan p_plan_rc[MAX_THREAD_NUM]; static rfftwnd_plan p_plan_cr[MAX_THREAD_NUM]; static fftw_real* p_u0[MAX_THREAD_NUM]; static fftw_real* p_v0[MAX_THREAD_NUM]; static int thread_id = -1; static int thread_lock = 0; #define floor(x) ((x)>=0.0 ? ((int)(x)) : (-((int)(1-(x))))) int init_SFSW(int n) { while (thread_lock) sleep(1); thread_lock = 1; thread_id++; // if (thread_id>=MAX_THREAD_NUM) { fprintf(stderr, "SFSW: Threads number is over!!\n"); fflush(stderr); thread_lock = 0; return -1; } // p_plan_rc[thread_id] = rfftw2d_create_plan(n, n, FFTW_REAL_TO_COMPLEX, FFTW_IN_PLACE); p_plan_cr[thread_id] = rfftw2d_create_plan(n, n, FFTW_COMPLEX_TO_REAL, FFTW_IN_PLACE); p_u0[thread_id] = (fftw_real*)malloc(sizeof(fftw_real)*n*(n+2)); p_v0[thread_id] = (fftw_real*)malloc(sizeof(fftw_real)*n*(n+2)); thread_lock = 0; return thread_id; } void free_SFSW(int thid) { rfftwnd_destroy_plan(p_plan_rc[thid]); rfftwnd_destroy_plan(p_plan_cr[thid]); // if (p_u0[thid]!=NULL) free(p_u0[thid]); if (p_v0[thid]!=NULL) free(p_v0[thid]); } void solve_SFSW(int n, float* u, float* v, float* fu, float* fv, int rsize, float visc, float dt, int thid) { fftw_real x, y, f, r_sq, U[2], V[2], s, t; int i, j, i0, j0, i1, j1; fftw_real* u0 = p_u0[thid]; fftw_real* v0 = p_v0[thid]; rfftwnd_plan plan_rc = p_plan_rc[thid]; rfftwnd_plan plan_cr = p_plan_cr[thid]; // for (i=0; i