/* * A Simple Fluid Solver Wind by Jos Stam for OpenSim * http://www.dgp.utoronto.ca/people/stam/reality/Research/pub.html * * Using FFTW v3.0 http://www.fftw.org * * Coded by Fumi.Iseki */ #include #include #include #include #include #define MAX_THREAD_NUM 36 static fftw_plan p_plan_rc_u[MAX_THREAD_NUM]; static fftw_plan p_plan_rc_v[MAX_THREAD_NUM]; static fftw_plan p_plan_cr_u[MAX_THREAD_NUM]; static fftw_plan p_plan_cr_v[MAX_THREAD_NUM]; static fftw_complex* p_cmp_u[MAX_THREAD_NUM]; static fftw_complex* p_cmp_v[MAX_THREAD_NUM]; static double* p_u0[MAX_THREAD_NUM]; static double* 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; } fftw_init_threads(); fftw_plan_with_nthreads(MAX_THREAD_NUM); p_cmp_u[thread_id] = (fftw_complex*)malloc(sizeof(fftw_complex)*n*(n/2+1)); p_cmp_v[thread_id] = (fftw_complex*)malloc(sizeof(fftw_complex)*n*(n/2+1)); p_u0[thread_id] = (double*)malloc(sizeof(double)*n*n); p_v0[thread_id] = (double*)malloc(sizeof(double)*n*n); fftw_complex* cmp_u = p_cmp_u[thread_id]; fftw_complex* cmp_v = p_cmp_v[thread_id]; double* u0 = p_u0[thread_id]; double* v0 = p_v0[thread_id]; // p_plan_rc_u[thread_id] = fftw_plan_dft_r2c_2d(n, n, u0, cmp_u, FFTW_ESTIMATE); p_plan_rc_v[thread_id] = fftw_plan_dft_r2c_2d(n, n, v0, cmp_v, FFTW_ESTIMATE); p_plan_cr_u[thread_id] = fftw_plan_dft_c2r_2d(n, n, cmp_u, u0, FFTW_ESTIMATE); p_plan_cr_v[thread_id] = fftw_plan_dft_c2r_2d(n, n, cmp_v, v0, FFTW_ESTIMATE); thread_lock = 0; return thread_id; } void free_SFSW(int thid) { fftw_plan plan_rc_u = p_plan_rc_u[thid]; fftw_plan plan_rc_v = p_plan_rc_v[thid]; fftw_plan plan_cr_u = p_plan_cr_u[thid]; fftw_plan plan_cr_v = p_plan_cr_v[thid]; if (plan_rc_u!=NULL) fftw_destroy_plan(plan_rc_u); if (plan_rc_v!=NULL) fftw_destroy_plan(plan_rc_v); if (plan_cr_u!=NULL) fftw_destroy_plan(plan_cr_u); if (plan_cr_v!=NULL) fftw_destroy_plan(plan_cr_v); fftw_cleanup_threads(); // fftw_complex* cmp_u = p_cmp_u[thid]; fftw_complex* cmp_v = p_cmp_v[thid]; double* u0 = p_u0[thid]; double* v0 = p_v0[thid]; // if (cmp_u!=NULL) fftw_free(cmp_u); if (cmp_v!=NULL) fftw_free(cmp_v); if (u0!=NULL) free(u0); if (v0!=NULL) free(v0); } void solve_SFSW(int n, float* u, float* v, float* fu, float* fv, int rsize, float visc, float dt, int thid) { double x, y, x0, y0, f, r, U[2], V[2], s, t; int i, j, i0, j0, i1, j1; fftw_complex* cmp_u = p_cmp_u[thid]; fftw_complex* cmp_v = p_cmp_v[thid]; double* u0 = p_u0[thid]; double* v0 = p_v0[thid]; fftw_plan plan_rc_u = p_plan_rc_u[thid]; fftw_plan plan_rc_v = p_plan_rc_v[thid]; fftw_plan plan_cr_u = p_plan_cr_u[thid]; fftw_plan plan_cr_v = p_plan_cr_v[thid]; // for (i=0; i