int main(int argc, char**argv) { int err; int i; double t0, t1; FmmvHandle _FMMV; FmmvHandle *FMMV = &_FMMV; void (*GEN_M)(FmmvHandle *FMMV, Box *box); void (*EVAL_M)(FmmvHandle *FMMV, Box *target, Box *source); void (*EVAL_L)(FmmvHandle *FMMV, Box *box); void (*GEN_L)(FmmvHandle *FMMV, Box *target, Box *source); void (*GEN_L_EVAL_M)(FmmvHandle *FMMV, Box *target, Box *source); void (*EVAL_DIRECT)(FmmvHandle *FMMV, Box *target, Box *source) = FMMV->eval_direct; Box _box_A; Box _box_B; Box *box_A = &_box_A; Box *box_B = &_box_B; Box _child_A[4]; Box _child_B[4]; int NParticles = 100; int NTargets = 100; _FLOAT_ (*particles)[2]; _FLOAT_ (*targets)[2] = NULL; _FLOAT_ *charges; _FLOAT_ (*dipoleMoments)[2] = NULL; _FLOAT_ x, y; _FLOAT_ *potM; _FLOAT_ *potL; _FLOAT_ (*gradM)[2] = NULL; _FLOAT_ (*gradL)[2] = NULL; _FLOAT_ *exPot; _FLOAT_ (*exGrad)[2] = NULL; _FLOAT_ errL2, errL2grad; double beta = 0.0; int pM = 8; int pL = 8; int s = 8; int *perm; int *permTargets; int with_dipoleSources=0; int with_gradients=0; int LM_combined=0; int with_M2M=0; int with_L2L=0; int printResult=0; #ifdef USE_SINGLE_PRECISION int exAcc=1; #else int exAcc=2; #endif //int exAcc=0; _FLOAT_ x_A = .125; _FLOAT_ y_A = .125; double size_A = .0625; int level_A = 2; _FLOAT_ x_B = .875; _FLOAT_ y_B = .875; double size_B = .0625; int level_B = 2; feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); set_from_command_line_double(argc, argv, "beta", &beta); set_from_command_line_bool(argc, argv, "dipoleSources", &with_dipoleSources); set_from_command_line_bool(argc, argv, "gradients", &with_gradients); set_from_command_line_bool(argc, argv, "printResult", &printResult); set_from_command_line_bool(argc, argv, "LM_combined", &LM_combined); set_from_command_line_bool(argc, argv, "M2M", &with_M2M); set_from_command_line_bool(argc, argv, "L2L", &with_L2L); set_from_command_line_int(argc, argv, "directEvalAccuracy", &exAcc); if (with_dipoleSources) { if (with_gradients) { FMMV->dataKind = FMM_ST_DIPOLE_GRAD; GEN_M = gen_M_ST_dipole_grad; EVAL_M = eval_M_ST_dipole_grad; GEN_L = gen_L_ST_dipole_grad; EVAL_L = eval_L_ST_dipole_grad; GEN_L_EVAL_M = gen_L_eval_M_dipole_grad; switch (exAcc) { case 0: EVAL_DIRECT = eval_direct_ST_dipole_grad_acc0; break; case 1: EVAL_DIRECT = eval_direct_ST_dipole_grad_acc1; break; #if FMM_PRECISION==1 case 2: EVAL_DIRECT = eval_direct_ST_dipole_grad_acc2; break; #endif } } else { FMMV->dataKind = FMM_ST_DIPOLE; GEN_M = gen_M_ST_dipole; EVAL_M = eval_M_ST_dipole; GEN_L = gen_L_ST_dipole; EVAL_L = eval_L_ST_dipole; GEN_L_EVAL_M = gen_L_eval_M_dipole; switch (exAcc) { case 0: EVAL_DIRECT = eval_direct_ST_dipole_acc0; break; case 1: EVAL_DIRECT = eval_direct_ST_dipole_acc1; break; #if FMM_PRECISION==1 case 2: EVAL_DIRECT = eval_direct_ST_dipole_acc2; break; #endif } } } else { if (with_gradients) { FMMV->dataKind = FMM_ST_GRAD; GEN_M = gen_M_ST_grad; EVAL_M = eval_M_ST_grad; GEN_L = gen_L_ST_grad; EVAL_L = eval_L_ST_grad; GEN_L_EVAL_M = gen_L_eval_M_grad; switch (exAcc) { case 0: EVAL_DIRECT = eval_direct_ST_grad_acc0; break; case 1: EVAL_DIRECT = eval_direct_ST_grad_acc1; break; #if FMM_PRECISION==1 case 2: EVAL_DIRECT = eval_direct_ST_grad_acc2; break; #endif } } else { FMMV->dataKind = FMM_ST_STANDARD; GEN_M = gen_M_ST_standard; EVAL_M = eval_M_ST_standard; GEN_L = gen_L_ST_standard; EVAL_L = eval_L_ST_standard; GEN_L_EVAL_M = gen_L_eval_M_standard; switch (exAcc) { case 0: EVAL_DIRECT = eval_direct_ST_standard_acc0; break; case 1: EVAL_DIRECT = eval_direct_ST_standard_acc1; break; #if FMM_PRECISION==1 case 2: EVAL_DIRECT = eval_direct_ST_standard_acc2; break; #endif } } } set_from_command_line_int(argc, argv, "NParticles", &NParticles); set_from_command_line_int(argc, argv, "NTargets", &NTargets); set_from_command_line_int(argc, argv, "pM", &pM); set_from_command_line_int(argc, argv, "pL", &pL); set_from_command_line_int(argc, argv, "s", &s); set_from_command_line_int(argc, argv, "level_A", &level_A); set_from_command_line_int(argc, argv, "level_B", &level_B); // set_from_command_line_double(argc, argv, "size_A", &size_A); // set_from_command_line_double(argc, argv, "size_B", &size_B); size_A = ldexp(1.0, -level_A); size_B = ldexp(1.0, -level_B); particles = (_FLOAT_ (*)[2]) calloc(NParticles, 2*sizeof(_FLOAT_)); charges = (_FLOAT_ *) calloc(NParticles, sizeof(_FLOAT_)); perm = (int *) calloc(NParticles, sizeof(int)); permTargets = (int *) calloc(NTargets, sizeof(int)); targets = (_FLOAT_ (*)[2]) calloc(NTargets, 2*sizeof(_FLOAT_)); potM = (_FLOAT_ *) calloc(NTargets, sizeof(_FLOAT_)); potL = (_FLOAT_ *) calloc(NTargets, sizeof(_FLOAT_)); exPot = (_FLOAT_ *) calloc(NTargets, sizeof(_FLOAT_)); if (with_gradients) { gradM = (_FLOAT_ (*)[2]) calloc(NTargets, 2*sizeof(_FLOAT_)); gradL = (_FLOAT_ (*)[2]) calloc(NTargets, 2*sizeof(_FLOAT_)); exGrad = (_FLOAT_ (*)[2]) calloc(NTargets, 2*sizeof(_FLOAT_)); } if (with_dipoleSources) { dipoleMoments = (_FLOAT_ (*)[2]) calloc(NParticles, 2*sizeof(_FLOAT_)); } FMMV->beta = beta; FMMV->pM = pM; FMMV->pL = pL; FMMV->s_eps = s; FMMV->particles = particles; FMMV->charges = charges; FMMV->dipoleMoments = dipoleMoments; FMMV->perm = perm; FMMV->NParticles = NParticles; FMMV->targets = targets; FMMV->permTargets = permTargets; FMMV->NTargets = NTargets; FMMV->scale = 1.0; FMMV->lambda = 0; my_srand(1481765933); box_A->firstParticle = 0; box_A->noOfParticles = NParticles; box_A->x = x_A; box_A->y = y_A; box_A->level = level_A; box_A->M = 0; /* if (with_M2M) */ { int m = NParticles/4; double d = 0.25*size_A; int c; for (c=0; c<4; c++) { box_A->child[c] = &_child_A[c]; box_A->child[c]->level = level_A + 1; box_A->child[c]->M = 0; box_A->child[c]->firstParticle = c*m; box_A->child[c]->noOfParticles = m; } box_A->child[3]->noOfParticles = NParticles - box_A->child[3]->firstParticle; box_A->child[SW]->x = x_A - d; box_A->child[SW]->y = y_A - d; box_A->child[NW]->x = x_A - d; box_A->child[NW]->y = y_A + d; box_A->child[SE]->x = x_A + d; box_A->child[SE]->y = y_A - d; box_A->child[NE]->x = x_A + d; box_A->child[NE]->y = y_A + d; for (c=0; c<4; c++) { for (i = box_A->child[c]->firstParticle; i < box_A->child[c]->firstParticle+box_A->child[c]->noOfParticles; i++) { x = box_A->child[c]->x + 2.0*d*(my_rand() / (_FLOAT_) MY_RAND_MAX) - d; y = box_A->child[c]->y + 2.0*d*(my_rand() / (_FLOAT_) MY_RAND_MAX) - d; particles[i][0] = x; particles[i][1] = y; } } } /* else { double d = size_A/2.0; for (i=0;i<NParticles;i++) { x = x_A + size_A*(my_rand() / (_FLOAT_) MY_RAND_MAX) - d; y = y_A + size_A*(my_rand() / (_FLOAT_) MY_RAND_MAX) - d; particles[i][0] = x; particles[i][1] = y; } }*/ for (i=0;i<NParticles;i++) { perm[i] = i; charges[i] = 1.0; } if (with_dipoleSources) { for (i=0;i<NParticles;i++) { x = (my_rand() / (_FLOAT_) MY_RAND_MAX) - 0.5; y = (my_rand() / (_FLOAT_) MY_RAND_MAX) - 0.5; dipoleMoments[i][0] = x; dipoleMoments[i][1] = y; } } box_B->firstTarget = 0; box_B->noOfTargets = NTargets; box_B->x = x_B; box_B->y = y_B; box_B->level = level_B; box_B->L = 0; /* if (with_L2L) */ { int m = NTargets/4; double d = 0.25*size_B; int c; for (c=0; c<4; c++) { box_B->child[c] = &_child_B[c]; box_B->child[c]->level = level_B + 1; box_B->child[c]->L = 0; box_B->child[c]->firstTarget = c*m; box_B->child[c]->noOfTargets = m; } box_B->child[3]->noOfTargets = NTargets - box_B->child[3]->firstTarget; box_B->child[SW]->x = x_B - d; box_B->child[SW]->y = y_B - d; box_B->child[NW]->x = x_B - d; box_B->child[NW]->y = y_B + d; box_B->child[SE]->x = x_B + d; box_B->child[SE]->y = y_B - d; box_B->child[NE]->x = x_B + d; box_B->child[NE]->y = y_B + d; for (c=0; c<4; c++) { for (i = box_B->child[c]->firstTarget; i < box_B->child[c]->firstTarget+box_B->child[c]->noOfTargets; i++) { x = box_B->child[c]->x + 2.0*d*(my_rand() / (_FLOAT_) MY_RAND_MAX) - d; y = box_B->child[c]->y + 2.0*d*(my_rand() / (_FLOAT_) MY_RAND_MAX) - d; targets[i][0] = x; targets[i][1] = y; } } } /* else { double d = size_B/2.0; for (i=0;i<NTargets;i++) { x = x_B + size_B*(my_rand() / (_FLOAT_) MY_RAND_MAX) - d; y = y_B + size_B*(my_rand() / (_FLOAT_) MY_RAND_MAX) - d; targets[i][0] = x; targets[i][1] = y; } } */ for (i=0;i<NTargets;i++) { permTargets[i] = i; } init_all(FMMV); err = ida_allocate(FMMV); copy_particles(FMMV); copy_charges(FMMV); zero_pot(FMMV); t0 = (double) clock()/CLOCKS_PER_SEC; EVAL_DIRECT(FMMV, box_B, box_A); t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (eval_direct) : %7.4f\n", t1); FMMV->potentials = exPot; FMMV->gradients = exGrad; backcopy_pot(FMMV); if (with_M2M||with_L2L) { // in init_M2M is initialisation als necessary for L2L init_M2M(FMMV, -1); } if (with_M2M) { int c; t0 = (double) clock()/CLOCKS_PER_SEC; for (c=0; c<4; c++) { GEN_M(FMMV, box_A->child[c]); } t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (GEN_M) : %7.4f\n", t1); //init_M2M(FMMV, -1); init_M2M(FMMV, level_A); t0 = (double) clock()/CLOCKS_PER_SEC; M2M(FMMV, box_A); t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (M2M) : %7.4f\n", t1); } else { t0 = (double) clock()/CLOCKS_PER_SEC; GEN_M(FMMV, box_A); t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (GEN_M) : %7.4f\n", t1); } /* printf("M:\n"); for (i=0;i<=pM;i++) { printf("%3i %24.16e %24.16e\n", i, box_A->M[2*i], box_A->M[2*i+1]); } */ zero_pot(FMMV); t0 = (double) clock()/CLOCKS_PER_SEC; EVAL_M(FMMV, box_B, box_A); t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (EVAL_M) : %7.4f\n", t1); FMMV->potentials = potM; FMMV->gradients = gradM; backcopy_pot(FMMV); t0 = (double) clock()/CLOCKS_PER_SEC; GEN_L(FMMV, box_B, box_A); t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (GEN_L) : %7.4f\n", t1); zero_pot(FMMV); if (with_L2L) { int c; init_L2L(FMMV, -1); init_L2L(FMMV, level_B); t0 = (double) clock()/CLOCKS_PER_SEC; L2L(FMMV, box_B); t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (L2L) : %7.4f\n", t1); t0 = (double) clock()/CLOCKS_PER_SEC; for (c=0; c<4; c++) { EVAL_L(FMMV, box_B->child[c]); } t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (EVAL_L) : %7.4f\n", t1); printf("L:\n"); for (i=0;i<=pL;i++) { printf("%3i %24.16e %24.16e\n", i, box_B->child[3]->L[2*i], box_B->child[3]->L[2*i+1]); } } else { t0 = (double) clock()/CLOCKS_PER_SEC; EVAL_L(FMMV, box_B); t1 = (double) clock()/CLOCKS_PER_SEC - t0; printf("time (EVAL_L) : %7.4f\n", t1); printf("L:\n"); for (i=0;i<=pL;i++) { printf("%3i %24.16e %24.16e\n", i, box_B->L[2*i], box_B->L[2*i+1]); } } FMMV->potentials = potL; FMMV->gradients = gradL; backcopy_pot(FMMV); ida_free(FMMV); if (with_gradients) { relL2Err(0, 0, 0); /* init */ relL2Err2(0, NULL, NULL); /* init */ if (printResult) { printf("\n Pot(M) Pot(exact) rel.err. rel.err.(grad)\n"); printf("============================================================\n"); } for (i=0; i<NTargets; i++) { relL2Err(1, potM[i], exPot[i]); /* accumulate */ relL2Err2(1, gradM[i], exGrad[i]); /* accumulate */ if (printResult) { printf("%3i %12.4e %12.4e %12.4e %12.4e\n", i, (double) potM[i], (double) exPot[i], (double) relErr(potM[i], exPot[i]),(_FLOAT_) relErr2(gradM[i], exGrad[i])); } } errL2 = relL2Err(2, 0, 0); /*finalize*/ errL2grad = relL2Err2(2, NULL, NULL); /*finalize*/ printf ("\nerr_L2(potM) = %.4e err_L2(gradM) = %.4e\n", errL2, errL2grad); printf("%24.16e %24.16e\n", exGrad[0][0], exGrad[0][1]); printf("%24.16e %24.16e\n", gradM[0][0], gradM[0][1]); relL2Err(0, 0, 0); /* init */ relL2Err2(0, NULL, NULL); /* init */ if (printResult) { printf("\n Pot(L) Pot(exact) rel.err. rel.err.(grad)\n"); printf("============================================================\n"); } for (i=0; i<NTargets; i++) { relL2Err(1, potL[i], exPot[i]); /* accumulate */ relL2Err2(1, gradL[i], exGrad[i]); /* accumulate */ if (printResult) { printf("%3i %12.4e %12.4e %12.4e %12.4e\n", i, (double) potL[i], (double) exPot[i], (double) relErr(potL[i], exPot[i]),(_FLOAT_) relErr2(gradL[i], exGrad[i])); } } errL2 = relL2Err(2, 0, 0); /*finalize*/ errL2grad = relL2Err2(2, NULL, NULL); /*finalize*/ printf ("\nerr_L2(potL) = %.4e err_L2(gradL) = %.4e\n", errL2, errL2grad); printf("%24.16e %24.16e\n", exGrad[0][0], exGrad[0][1]); printf("%24.16e %24.16e\n", gradL[0][0], gradL[0][1]); } else { relL2Err(0, 0, 0); if (printResult) { printf("\n Pot(M) Pot(exact) rel.err.\n"); printf("============================================\n"); } for (i=0; i<NTargets; i++) { relL2Err(1, potM[i], exPot[i]); /* accumulate */ if (printResult) { printf("%3i %12.4e %12.4e %12.4e\n", i, (double) potM[i], (double) exPot[i], (double) relErr(potM[i], exPot[i])); } } errL2 = relL2Err(2, 0, 0); /*finalize*/ printf ("\nerr_L2(potM) = %.4e\n", errL2); relL2Err(0, 0, 0); if (printResult) { printf("\n Pot(L) Pot(exact) rel.err.\n"); printf("============================================\n"); } for (i=0; i<NTargets; i++) { relL2Err(1, potL[i], exPot[i]); /* accumulate */ if (printResult) { printf("%3i %12.4e %12.4e %12.4e\n", i, (double) potL[i], (double) exPot[i], (double) relErr(potL[i], exPot[i])); } } errL2 = relL2Err(2, 0, 0); /*finalize*/ printf ("\nerr_L2(potL) = %.4e\n", errL2); } // TODO: deallocate... finish_all(FMMV); return 0; }
void monthranger(int y, int m, int jd_flag, int before, int after) { struct monthlines year[12]; struct weekdays wds; char s[MAX_WIDTH], t[MAX_WIDTH]; int i, j; int mpl; int mw; int m1, m2; int prevyear = -1; int printyearheader; mpl = jd_flag ? 3 : 4; mw = jd_flag ? MONTH_WIDTH_R_J : MONTH_WIDTH_R; while (before != 0) { DECREASEMONTH(m, y); before--; after++; } m1 = y * 12 + m - 1; m2 = m1 + after; mkweekdays(&wds); /* * The year header is printed when there are more than 'mpl' months * and if the first month is a multitude of 'mpl'. * If not, it will print the year behind every month. */ printyearheader = (after >= mpl - 1) && (M2M(m1) - 1) % mpl == 0; m = m1; while (m <= m2) { int count = 0; for (i = 0; i != mpl && m + i <= m2; i++) { mkmonthr(M2Y(m + i), M2M(m + i) - 1, jd_flag, year + i); count++; } /* Empty line between two rows of months. */ if (m != m1) printf("\n"); /* Year at the top. */ if (printyearheader && M2Y(m) != prevyear) { sprintf(s, "%d", M2Y(m)); printf("%s\n", center(t, s, mpl * mw)); prevyear = M2Y(m); } /* Month names. */ wprintf(L" "); for (i = 0; i < count; i++) if (printyearheader) wprintf(L"%-*ls", mw, year[i].name); else wprintf(L"%-ls %-*d", year[i].name, mw - wcslen(year[i].name) - 1, M2Y(m + i)); printf("\n"); /* And the days of the month. */ for (i = 0; i != 7; i++) { /* Week day */ wprintf(L"%.2ls", wds.names[i]); /* Full months */ for (j = 0; j < count; j++) printf("%-*s", MW(mw, year[j].extralen[i]), year[j].lines[i]); printf("\n"); } /* Week numbers. */ if (flag_weeks) { printf(" "); for (i = 0; i < count; i++) printf("%-*s", mw, year[i].weeks); printf("\n"); } m += mpl; } return; }
void* non_adaptive_fmm_periodic_ws2(GenericFmmThreadArg *arg) { FmmvHandle *FMMV = arg->fh; int thread = arg->thread; Box *box, *box1, *box2; int level; int i, j, k, jj; void (*GEN_M)(FmmvHandle *FMMV, Box *box) = FMMV->gen_M; void (*EVAL_L)(FmmvHandle *FMMV, Box *box) = FMMV->eval_L; void (*EVAL_DIRECT)(FmmvHandle *FMMV, Box *target, Box *source) = FMMV->eval_direct; void (*EVAL_DIRECT_periodic)(FmmvHandle *FMMV, Box *target, Box *source, _FLOAT_ dx, _FLOAT_ dy #if (FMM_DIM>=3) , _FLOAT_ dz #endif ) = FMMV->eval_direct_periodic; switch(thread) { case (FARFIELD_THREAD): stat_start(FMMV, STAT_FARFIELD); break; case (NEARFIELD_THREAD): stat_start(FMMV, STAT_NEARFIELD); break; default: break; } if ((thread==STANDARD_THREAD)||(thread==FARFIELD_THREAD)) { /*** Upward Pass ***/ /* Form multipole expansions at finest level */ stat_start(FMMV, STAT_GEN_M); for (box=FMMV->firstSourceBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextSourceBox) { GEN_M(FMMV, box); } stat_stop(FMMV, STAT_GEN_M); /* Form multipole expansions at coarser levels by merging */ stat_start(FMMV, STAT_M2M); init_M2M(FMMV, -1); for (level=FMMV->maxLevel-1; level>=0; level--) {/* note: now compute M up to level 0 */ for (box=FMMV->firstSourceBoxOfLevel[level]; box!=0; box=box->nextSourceBox) { init_M2M(FMMV, level); M2M(FMMV, box); } } finish_M2M(FMMV); stat_stop(FMMV, STAT_M2M); /*** Downward Pass ***/ stat_start(FMMV, STAT_M2L); init_M2L(FMMV, -1); /******************************************************************/ FMMV->firstSourceBoxOfLevel[0]->L = (_FLOAT_ *) FMMV_MALLOC(FMMV, FMM_SIZE_OF_L(FMMV->pL)*sizeof(_FLOAT_)); #ifdef USE_PTHREADS if (thread==FARFIELD_THREAD) { pthread_mutex_lock(&(FMMV->firstSourceBoxOfLevel[0]->mutex)); } #endif periodic_lattice_M2L(FMMV, FMMV->firstSourceBoxOfLevel[0]->M, FMMV->firstSourceBoxOfLevel[0]->L); #ifdef USE_PTHREADS if (thread==FARFIELD_THREAD) { pthread_mutex_unlock(&(FMMV->firstSourceBoxOfLevel[0]->mutex)); } #endif FREE_M(FMMV, FMMV->firstSourceBoxOfLevel[0]->M); /******************************************************************/ if (FMMV->reducedScheme) { /* we need an artificial parent for root */ Box parentOfRoot; box = FMMV->firstSourceBoxOfLevel[0]; parentOfRoot.level = -1; box->whichChild=0; box->parent=&parentOfRoot; for (i=0; i<FMM_CHILDS_PER_BOX; i++) { parentOfRoot.child[i] = box; } for (i=0; i<26; i++) { parentOfRoot.neighbor[i] = &parentOfRoot; } for (i=0; i<6; i++) { parentOfRoot.X[i] = 0; parentOfRoot.X2[i] = 0; } init_M2L(FMMV, 1); M2L_ws2_reduced(FMMV, &parentOfRoot); box = FMMV->firstSourceBoxOfLevel[0]; for (i=0; i<FMM_CHILDS_PER_BOX; i++) { if (box->child[i]) { FREE_M(FMMV, box->child[i]->M); } } for (level=2; level<=FMMV->maxLevel; level++) { /* Convert multipole to exponential expansions and shift exponential expansions */ init_M2L(FMMV, level); for (box=FMMV->firstSourceBoxOfLevel[level-2]; box!=0; box=box->nextSourceBox) { M2L_ws2_reduced(FMMV, box); for (i=0; i<FMM_CHILDS_PER_BOX; i++) { if (box->child[i]) { for (j=0; j<FMM_CHILDS_PER_BOX; j++) { if (box->child[i]->child[j]) { FREE_M(FMMV, box->child[i]->child[j]->M); } } } } } } } else { for (level=1; level<=FMMV->maxLevel; level++) { /* Convert multipole to exponential expansions and shift exponential expansions */ init_M2L(FMMV, level); for (box=FMMV->firstSourceBoxOfLevel[level-1]; box!=0; box=box->nextSourceBox) { M2L_ws2(FMMV, box); for (i=0; i<FMM_CHILDS_PER_BOX; i++) { if (box->child[i]) FREE_M(FMMV, box->child[i]->M); } } } } finish_M2L(FMMV); stat_stop(FMMV, STAT_M2L); /* Shift local expansions from each parent to each of its children */ stat_start(FMMV, STAT_L2L); init_L2L(FMMV, -1); for (level=1; level<=FMMV->maxLevel; level++) { init_L2L(FMMV, level-1); for (box=FMMV->firstTargetBoxOfLevel[level-1]; box!=0; box=box->nextTargetBox) { L2L(FMMV, box); FREE_L(FMMV, box->L); } } finish_L2L(FMMV); stat_stop(FMMV, STAT_L2L); /*** Evaluation of Potentials ***/ stat_start(FMMV, STAT_EVAL_L); if (thread==STANDARD_THREAD) { for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) { /* Evaluate local expansions at finest level */ EVAL_L(FMMV, box); FREE_L(FMMV, box->L); } } /* if (thread==STANDARD_THREAD) */ #ifdef USE_PTHREADS else { /* if (thread==FARFIELD_THREAD) */ for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) { /* Evaluate local expansions at finest level */ pthread_mutex_lock(&(box->mutex)); pthread_mutex_lock(&(box->parent->mutex)); EVAL_L(FMMV, box); pthread_mutex_unlock(&(box->mutex)); pthread_mutex_unlock(&(box->parent->mutex)); FREE_L(FMMV, box->L); } } /* if (thread==FARFIELD_THREAD) */ #endif stat_stop(FMMV, STAT_EVAL_L); } /* if ((thread==STANDARD_THREAD)||(thread==FARFIELD_THREAD)) */ if (thread==STANDARD_THREAD) { stat_start(FMMV, STAT_LIST1); if (FMMV->maxLevel==0) { int dx, dy; #if (FMM_DIM>=3) int dz; #endif box=FMMV->firstTargetBoxOfLevel[0]; EVAL_DIRECT(FMMV, box, box); for (dx=-2; dx<=+2; dx++) { for (dy=-2; dy<=+2; dy++) { #if (FMM_DIM>=3) for (dz=-2; dz<=+2; dz++) { #endif if (!((dx==0)&&(dy==0) #if (FMM_DIM>=3) &&(dz==0) #endif )) { EVAL_DIRECT_periodic(FMMV, box, box, dx, dy #if (FMM_DIM>=3) , dz #endif ); } #if (FMM_DIM>=3) } #endif }} } else { for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel-1]; box!=0; box=box->nextTargetBox) { EVAL_DIRECT(FMMV, box, box); } for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) { for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) { box1 = box->parent->neighbor[k=theseParentNeighbors[box->whichChild][i]]; if (isSource(box1)) { /*&& (box1->firstParticle < box->firstParticle) */ jj=((box->parent->atBoundary) & (boundarysData[k])); EVAL_DIRECT_periodic(FMMV, box, box1, pS[jj].dx, pS[jj].dy #if (FMM_DIM>=3) , pS[jj].dz #endif ); } } for (i=0; i<N_OTHER_NEIGHBORS; i++) { box1 = box->parent->neighbor[k=otherParentNeighborsChilds[box->whichChild][i][0]]; if (isSource(box1)) { jj=((box->parent->atBoundary) & (boundarysData[k])); for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) { box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]]; EVAL_DIRECT_periodic(FMMV, box, box2, pS[jj].dx, pS[jj].dy #if (FMM_DIM>=3) , pS[jj].dz #endif ); } } } } } stat_stop(FMMV, STAT_LIST1); } /* if (thread==STANDARD_THREAD) */ #ifdef USE_PTHREADS if (thread==NEARFIELD_THREAD) { stat_start(FMMV, STAT_LIST1); if (FMMV->maxLevel==0) { int dx, dy; #if (FMM_DIM>=3) int dz; #endif box=FMMV->firstTargetBoxOfLevel[0]; pthread_mutex_lock(&(box->mutex)); EVAL_DIRECT(FMMV, box, box); for (dx=-2; dx<=+2; dx++) { for (dy=-2; dy<=+2; dy++) { #if (FMM_DIM>=3) for (dz=-2; dz<=+2; dz++) { #endif if (!((dx==0)&&(dy==0) #if (FMM_DIM>=3) &&(dz==0) #endif )) { EVAL_DIRECT_periodic(FMMV, box, box, dx, dy #if (FMM_DIM>=3) , dz #endif ); } #if (FMM_DIM>=3) } #endif }} pthread_mutex_unlock(&(box->mutex)); } else { for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel-1]; box!=0; box=box->nextTargetBox) { pthread_mutex_lock(&(box->mutex)); EVAL_DIRECT(FMMV, box, box); pthread_mutex_unlock(&(box->mutex)); } for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) { pthread_mutex_lock(&(box->mutex)); if (FMMV->targets) { /* no lock for source boxes */ for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) { box1 = box->parent->neighbor[k=theseParentNeighbors[box->whichChild][i]]; if (isSource(box1)) { /*&& (box1->firstParticle < box->firstParticle) */ jj=((box->parent->atBoundary) & (boundarysData[k])); EVAL_DIRECT_periodic(FMMV, box, box1, pS[jj].dx, pS[jj].dy #if (FMM_DIM>=3) , pS[jj].dz #endif ); } } for (i=0; i<N_OTHER_NEIGHBORS; i++) { box1 = box->parent->neighbor[k=otherParentNeighborsChilds[box->whichChild][i][0]]; if (isSource(box1)) { /* && (box1->firstParticle < box->firstParticle)) { */ jj=((box->parent->atBoundary) & (boundarysData[k])); for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) { box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]]; if(box2) { EVAL_DIRECT_periodic(FMMV, box, box2, pS[jj].dx, pS[jj].dy #if (FMM_DIM>=3) , pS[jj].dz #endif ); } } } } } else { for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) { box1 = box->parent->neighbor[k=theseParentNeighbors[box->whichChild][i]]; if (isSource(box1)) { /*&& (box1->firstParticle < box->firstParticle) */ jj=((box->parent->atBoundary) & (boundarysData[k])); pthread_mutex_lock(&(box1->mutex)); EVAL_DIRECT_periodic(FMMV, box, box1, pS[jj].dx, pS[jj].dy #if (FMM_DIM>=3) , pS[jj].dz #endif ); pthread_mutex_unlock(&(box1->mutex)); } } for (i=0; i<N_OTHER_NEIGHBORS; i++) { box1 = box->parent->neighbor[k=otherParentNeighborsChilds[box->whichChild][i][0]]; if (isSource(box1)) { /* && (box1->firstParticle < box->firstParticle)) { */ jj=((box->parent->atBoundary) & (boundarysData[k])); for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) { box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]]; if(box2) { pthread_mutex_lock(&(box2->mutex)); EVAL_DIRECT_periodic(FMMV, box, box2, pS[jj].dx, pS[jj].dy #if (FMM_DIM>=3) , pS[jj].dz #endif ); pthread_mutex_unlock(&(box2->mutex)); } } } } } pthread_mutex_unlock(&(box->mutex)); } } stat_stop(FMMV, STAT_LIST1); } /* if (thread==NEARFIELD_THREAD) */ #endif switch(thread) { case (FARFIELD_THREAD): stat_stop(FMMV, STAT_FARFIELD); break; case (NEARFIELD_THREAD): stat_stop(FMMV, STAT_NEARFIELD); break; default: break; } return 0; }
/* Print all months for the period in the range [ before .. y-m .. after ]. */ void monthrangeb(int y, int m, int jd_flag, int before, int after) { struct monthlines year[12]; struct weekdays wds; char s[MAX_WIDTH], t[MAX_WIDTH]; wchar_t ws[MAX_WIDTH], ws1[MAX_WIDTH]; const char *wdss; int i, j; int mpl; int mw; int m1, m2; int printyearheader; int prevyear = -1; mpl = jd_flag ? 2 : 3; mw = jd_flag ? MONTH_WIDTH_B_J : MONTH_WIDTH_B; wdss = (mpl == 2) ? " " : ""; while (before != 0) { DECREASEMONTH(m, y); before--; after++; } m1 = y * 12 + m - 1; m2 = m1 + after; mkweekdays(&wds); /* * The year header is printed when there are more than 'mpl' months * and if the first month is a multitude of 'mpl'. * If not, it will print the year behind every month. */ printyearheader = (after >= mpl - 1) && (M2M(m1) - 1) % mpl == 0; m = m1; while (m <= m2) { int count = 0; for (i = 0; i != mpl && m + i <= m2; i++) { mkmonthb(M2Y(m + i), M2M(m + i) - 1, jd_flag, year + i); count++; } /* Empty line between two rows of months */ if (m != m1) printf("\n"); /* Year at the top. */ if (printyearheader && M2Y(m) != prevyear) { sprintf(s, "%d", M2Y(m)); printf("%s\n", center(t, s, mpl * mw)); prevyear = M2Y(m); } /* Month names. */ for (i = 0; i < count; i++) if (printyearheader) wprintf(L"%-*ls ", mw, wcenter(ws, year[i].name, mw)); else { swprintf(ws, sizeof(ws), L"%-ls %d", year[i].name, M2Y(m + i)); wprintf(L"%-*ls ", mw, wcenter(ws1, ws, mw)); } printf("\n"); /* Day of the week names. */ for (i = 0; i < count; i++) { wprintf(L"%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls ", wdss, wds.names[6], wdss, wds.names[0], wdss, wds.names[1], wdss, wds.names[2], wdss, wds.names[3], wdss, wds.names[4], wdss, wds.names[5]); } printf("\n"); /* And the days of the month. */ for (i = 0; i != 6; i++) { for (j = 0; j < count; j++) printf("%-*s ", MW(mw, year[j].extralen[i]), year[j].lines[i]+1); printf("\n"); } m += mpl; } }
void* non_adaptive_fmm_ws2(GenericFmmThreadArg *arg) { FmmvHandle *FMMV = arg->fh; int thread = arg->thread; Box *box, *box1, *box2; int level; int i, j; void (*GEN_M)(FmmvHandle *FMMV, Box *box) = FMMV->gen_M; void (*EVAL_L)(FmmvHandle *FMMV, Box *box) = FMMV->eval_L; void (*EVAL_DIRECT)(FmmvHandle *FMMV, Box *target, Box *source) = FMMV->eval_direct; switch(thread) { case (FARFIELD_THREAD): stat_start(FMMV, STAT_FARFIELD); break; case (NEARFIELD_THREAD): stat_start(FMMV, STAT_NEARFIELD); break; default: break; } if ((thread==STANDARD_THREAD)||(thread==FARFIELD_THREAD)) { /*** Upward Pass ***/ /* Form multipole expansions at finest level */ stat_start(FMMV, STAT_GEN_M); if (FMMV->maxLevel>1) { for (box=FMMV->firstSourceBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextSourceBox) { GEN_M(FMMV, box); } } stat_stop(FMMV, STAT_GEN_M); /* Form multipole expansions at coarser levels by merging */ stat_start(FMMV, STAT_M2M); init_M2M(FMMV, -1); for (level=FMMV->maxLevel-1; level>=2; level--) { init_M2M(FMMV, level); for (box=FMMV->firstSourceBoxOfLevel[level]; box!=0; box=box->nextSourceBox) { M2M(FMMV, box); } } finish_M2M(FMMV); stat_stop(FMMV, STAT_M2M); /*** Downward Pass ***/ stat_start(FMMV, STAT_M2L); init_M2L(FMMV, -1); if (FMMV->reducedScheme) { for (level=2; level<=FMMV->maxLevel; level++) { init_M2L(FMMV, level); /* Convert multipole to exponential expansions and shift exponential expansions */ for (box=FMMV->firstSourceBoxOfLevel[level-2]; box!=0; box=box->nextSourceBox) { M2L_ws2_reduced(FMMV, box); for (i=0; i<FMM_CHILDS_PER_BOX; i++) { if (box->child[i]) { for (j=0; j<FMM_CHILDS_PER_BOX; j++) { if (box->child[i]->child[j]) { FREE_M(FMMV, box->child[i]->child[j]->M); } } } } } } } else { for (level=2; level<=FMMV->maxLevel; level++) { init_M2L(FMMV, level); /* Convert multipole to exponential expansions and shift exponential expansions */ for (box=FMMV->firstSourceBoxOfLevel[level-1]; box!=0; box=box->nextSourceBox) { M2L_ws2(FMMV, box); for (i=0; i<FMM_CHILDS_PER_BOX; i++) { if (box->child[i]) FREE_M(FMMV, box->child[i]->M); } } } } finish_M2L(FMMV); stat_stop(FMMV, STAT_M2L); /* Shift local expansions from each parent to each of its children */ stat_start(FMMV, STAT_L2L); init_L2L(FMMV, -1); for (level=2; level<=FMMV->maxLevel; level++) { init_L2L(FMMV, level-1); for (box=FMMV->firstTargetBoxOfLevel[level-1]; box!=0; box=box->nextTargetBox) { L2L(FMMV, box); FREE_L(FMMV, box->L); } } finish_L2L(FMMV); stat_stop(FMMV, STAT_L2L); /*** Evaluation of Potentials ***/ stat_start(FMMV, STAT_EVAL_L); if (thread==STANDARD_THREAD) { if (FMMV->maxLevel>1) { for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) { /* Evaluate local expansions at finest level */ EVAL_L(FMMV, box); FREE_L(FMMV, box->L); } } } /* if (thread==STANDARD_THREAD) */ #ifdef USE_PTHREADS else { /* if (thread==FARFIELD_THREAD) */ if (FMMV->maxLevel>1) { for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) { /* Evaluate local expansions at finest level */ pthread_mutex_lock(&(box->parent->mutex)); pthread_mutex_lock(&(box->mutex)); EVAL_L(FMMV, box); pthread_mutex_unlock(&(box->mutex)); pthread_mutex_unlock(&(box->parent->mutex)); FREE_L(FMMV, box->L); } } } /* if (thread==FARFIELD_THREAD) */ #endif stat_stop(FMMV, STAT_EVAL_L); } /* if ((thread==STANDARD_THREAD)||(thread==FARFIELD_THREAD)) */ if (thread==STANDARD_THREAD) { stat_start(FMMV, STAT_LIST1); if (FMMV->maxLevel<=1) { box=FMMV->firstTargetBoxOfLevel[0]; EVAL_DIRECT(FMMV, box, box); } else { for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel-1]; box!=0; box=box->nextTargetBox) { EVAL_DIRECT(FMMV, box, box); } for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) { for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) { box1 = box->parent->neighbor[theseParentNeighbors[box->whichChild][i]]; EVAL_DIRECT(FMMV, box, box1); } for (i=0; i<N_OTHER_NEIGHBORS; i++) { box1 = box->parent->neighbor[otherParentNeighborsChilds[box->whichChild][i][0]]; if (isSource(box1)) { for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) { box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]]; EVAL_DIRECT(FMMV, box, box2); } } } } } stat_stop(FMMV, STAT_LIST1); } /* if (thread==STANDARD_THREAD) */ #ifdef USE_PTHREADS if (thread==NEARFIELD_THREAD) { stat_start(FMMV, STAT_LIST1); if (FMMV->maxLevel<=1) { box=FMMV->firstTargetBoxOfLevel[0]; EVAL_DIRECT(FMMV, box, box); } else { for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel-1]; box!=0; box=box->nextTargetBox) { pthread_mutex_lock(&(box->mutex)); EVAL_DIRECT(FMMV, box, box); pthread_mutex_unlock(&(box->mutex)); } for (box=FMMV->firstTargetBoxOfLevel[FMMV->maxLevel]; box!=0; box=box->nextTargetBox) { pthread_mutex_lock(&(box->mutex)); if (FMMV->targets) { /* no lock for source boxes */ for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) { box1 = box->parent->neighbor[theseParentNeighbors[box->whichChild][i]]; if (box1) { EVAL_DIRECT(FMMV, box, box1); } } for (i=0; i<N_OTHER_NEIGHBORS; i++) { box1 = box->parent->neighbor[otherParentNeighborsChilds[box->whichChild][i][0]]; if (isSource(box1)) { for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) { box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]]; if (box2) { EVAL_DIRECT(FMMV, box, box2); } } } } } else { for (i=0; i<FMM_CHILDS_PER_BOX-1; i++) { box1 = box->parent->neighbor[theseParentNeighbors[box->whichChild][i]]; if (box1) { pthread_mutex_lock(&(box1->mutex)); EVAL_DIRECT(FMMV, box, box1); pthread_mutex_unlock(&(box1->mutex)); } } for (i=0; i<N_OTHER_NEIGHBORS; i++) { box1 = box->parent->neighbor[otherParentNeighborsChilds[box->whichChild][i][0]]; if (isSource(box1)) { for (j=2; j<otherParentNeighborsChilds[box->whichChild][i][1]+2; j++) { box2 = box1->child[otherParentNeighborsChilds[box->whichChild][i][j]]; if (box2) { pthread_mutex_lock(&(box2->mutex)); EVAL_DIRECT(FMMV, box, box2); pthread_mutex_unlock(&(box2->mutex)); } } } } } pthread_mutex_unlock(&(box->mutex)); } } stat_stop(FMMV, STAT_LIST1); } /* if (thread==NEARFIELD_THREAD) */ #endif switch(thread) { case (FARFIELD_THREAD): stat_stop(FMMV, STAT_FARFIELD); break; case (NEARFIELD_THREAD): stat_stop(FMMV, STAT_NEARFIELD); break; default: break; } return 0; }