/* obj prod_eval0(list l, obj (*func)(obj, obj)){ obj lt,rt,rr; assert(!! l); lt = eval(fpp(l)); rr = lt; for(; l; ){ rt = eval(fpp(l)); rr = call_fn(func, lt, rt); release(lt); release(rt); lt = rr; } return rr; } */ obj prod_eval(list l, obj (*func)(obj, obj)){ assert(!! l); obj rr = eval(fpp(l)); for(; l; ){ push(rr); push(eval(fpp(l))); rr = call_fn(func, sp1, sp0); release(pop(&is)); release(pop(&is)); } return rr; }
inline obj evalCond(obj exp){ list l = ul(exp); push(eval(fpp(l))); push(eval(fpp(l))); int c = uint(fpp(l)); obj rr = compare(c, sp1, sp0); release(sp1); sp1 = rr; for(; l;){ push(eval(fpp(l))); c = uint(fpp(l)); sp2 = and1(sp2, compare(c, sp1, sp0)); // and1 releases both release(sp1); sp1 = sp0; pop(&is); // should be nil } release(pop(&is)); return pop(&is); }
obj exec(obj v){ obj rr=nil; if(type(v)!=LIST && type(v)!=tExec) return eval(v); for(list l = ul(v); l; ){ if(rr) release(rr); rr = eval(fpp(l)); if(rr && type(rr)==tSigRet) break; if(rr && type(rr)==tBreak) break; } return rr; }
int main(){ enum{ NP = 128, NC = 8, NC3 = NC*NC*NC, PFMM = 7, ICUT = 2, }; typedef Cell_FMM<PFMM> Cell_t; static Particle ptcl[NP]; static Cell_t cell[NC][NC][NC]; const double clen = 1.0 / NC; for(int k=0; k<NC; k++){ for(int j=0; j<NC; j++){ for(int i=0; i<NC; i++){ cell[k][j][i].set(ivec3(i,j,k), clen); } } } Particle::gen_rand_dist(NP, ptcl); double msum = 0.0; for(int i=0; i<NP; i++){ msum += ptcl[i].mass; } // printf("msum = %e\n", msum); for(int i=0; i<NP; i++){ const ivec3 idx = cell_nearest(ptcl[i].pos, clen); assert(0 <= idx.x && idx.x < NC); assert(0 <= idx.y && idx.y < NC); assert(0 <= idx.z && idx.z < NC); cell[idx.z][idx.y][idx.x].plist.push_back(&ptcl[i]); } for(int k=0; k<NC; k++) for(int j=0; j<NC; j++) for(int i=0; i<NC; i++){ cell[k][j][i].sanity_check(); } puts("Eval PP"); PP_interact_OBC<PFMM, ICUT, NC, NC, NC> (cell); puts("Gen Green"); static GreenFunction_OBC<PFMM, NC, NC, NC> gf; gf.gen_gf_r(ICUT, 1./NC); gf.gen_gf_k(); puts("Eval PM"); Cell_t *cell1d = cell[0][0]; for(int i=0; i<NC3; i++){ cell1d[i].do_P2M(); } M2L_convolution_OBC<PFMM, NC, NC, NC> (gf, cell); for(int i=0; i<NC3; i++){ cell1d[i].do_L2P(); } dvec3 fpp(0.0), fpm(0.0); for(int i=0; i<NP; i++){ fpp += ptcl[i].mass * ptcl[i].acc_direct; fpm += ptcl[i].mass * ptcl[i].acc_app; } printf("PP ftot : (%e, %e, %e)\n", fpp.x, fpp.y, fpp.z); printf("PM ftot : (%e, %e, %e)\n", fpm.x, fpm.y, fpm.z); for(int i=0; i<NP; i++){ ptcl[i].move_accp(); } puts("eval dirct force"); #pragma omp parallel for for(int i=0; i<NP; i++){ Particle &pi = ptcl[i]; for(int j=0; j<NP; j++){ const Particle pj = ptcl[j]; if(j == i) continue; const dvec3 dr = pj.pos - pi.pos; const double r2 = dr*dr; const double ri2 = 1.0 / r2; const double ri = sqrt(ri2); const double ri3 = ri * ri2; pi.phi_direct += pj.mass * ri; pi.acc_direct += (pj.mass * ri3) * dr; } } #if 1 std::vector<double> err(NP); for(int i=0; i<NP; i++) err[i] = ptcl[i].adiff_rel(); std::sort(err.begin(), err.end()); print_err(err, "adiffr", ICUT, PFMM); for(int i=0; i<NP; i++) err[i] = ptcl[i].pdiff_rel(); std::sort(err.begin(), err.end()); print_err(err, "pdiffr", ICUT, PFMM); #endif return 0; }
inline list evalList(list l){ push(List2v((list)nil)); for(;l;) ul(sp0) = cons(eval(fpp(l)), ul(sp0)); obj rr = pop(&is); return reverse(strip2list(rr)); }