void grid_last(t_grid *grid, int cg0, int cg1, int ncg) { int CG0[2], CG1[2]; int i, m; int ci, not_used, ind, ncells; int *cell_index = grid->cell_index; int *nra = grid->nra; int *index = grid->index; int *a = grid->a; ncells = grid->ncells; if (ncells <= 0) { gmx_fatal(FARGS, "Number of grid cells is zero. Probably the system and box collapsed.\n"); } not_used = ci_not_used(grid->n); calc_bor(cg0, cg1, ncg, CG0, CG1); for (m = 0; (m < 2); m++) { for (i = CG0[m]; (i < CG1[m]); i++) { ci = cell_index[i]; if (ci != not_used) { range_check_mesg(ci, 0, ncells, range_warn); ind = index[ci]+nra[ci]++; range_check_mesg(ind, 0, grid->nr, range_warn); a[ind] = i; } } } }
void calc_ptrs(t_grid *grid) { int *index = grid->index; int *nra = grid->nra; int ix, iy, iz, ci, nr; int nnra, ncells; ncells = grid->ncells; if (ncells <= 0) { gmx_fatal(FARGS, "Number of grid cells is zero. Probably the system and box collapsed.\n"); } ci = nr = 0; for (ix = 0; (ix < grid->n[XX]); ix++) { for (iy = 0; (iy < grid->n[YY]); iy++) { for (iz = 0; (iz < grid->n[ZZ]); iz++, ci++) { range_check_mesg(ci, 0, ncells, range_warn); index[ci] = nr; nnra = nra[ci]; nr += nnra; nra[ci] = 0; } } } }
void ci2xyz(t_grid *grid, int i, int *x, int *y, int *z) /* Return x,y and z from the cell index */ { int ci; range_check_mesg(i, 0, grid->nr, range_warn); ci = grid->cell_index[i]; *x = ci / (grid->n[YY]*grid->n[ZZ]); ci -= (*x)*grid->n[YY]*grid->n[ZZ]; *y = ci / grid->n[ZZ]; ci -= (*y)*grid->n[ZZ]; *z = ci; }
void check_grid(t_grid *grid) { int ix, iy, iz, ci, cci, nra; if (grid->ncells <= 0) { gmx_fatal(FARGS, "Number of grid cells is zero. Probably the system and box collapsed.\n"); } ci = 0; cci = 0; for (ix = 0; (ix < grid->n[XX]); ix++) { for (iy = 0; (iy < grid->n[YY]); iy++) { for (iz = 0; (iz < grid->n[ZZ]); iz++, ci++) { if (ci > 0) { nra = grid->index[ci]-grid->index[cci]; if (nra != grid->nra[cci]) { gmx_fatal(FARGS, "nra=%d, grid->nra=%d, cci=%d", nra, grid->nra[cci], cci); } } cci = xyz2ci(grid->n[YY], grid->n[ZZ], ix, iy, iz); range_check_mesg(cci, 0, grid->ncells, range_warn); if (cci != ci) { gmx_fatal(FARGS, "ci = %d, cci = %d", ci, cci); } } } } }
int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) { int i, j, is; rvec dx_start, trial; real d2min, d2trial; ivec ishift, ishift_start; rvec_sub(x1, x2, dx); clear_ivec(ishift); switch (pbc->ePBCDX) { case epbcdxRECTANGULAR: for (i = 0; i < DIM; i++) { if (dx[i] > pbc->hbox_diag[i]) { dx[i] -= pbc->fbox_diag[i]; ishift[i]--; } else if (dx[i] <= pbc->mhbox_diag[i]) { dx[i] += pbc->fbox_diag[i]; ishift[i]++; } } break; case epbcdxTRICLINIC: /* For triclinic boxes the performance difference between * if/else and two while loops is negligible. * However, the while version can cause extreme delays * before a simulation crashes due to large forces which * can cause unlimited displacements. * Also allowing multiple shifts would index fshift beyond bounds. */ for (i = DIM-1; i >= 1; i--) { if (dx[i] > pbc->hbox_diag[i]) { for (j = i; j >= 0; j--) { dx[j] -= pbc->box[i][j]; } ishift[i]--; } else if (dx[i] <= pbc->mhbox_diag[i]) { for (j = i; j >= 0; j--) { dx[j] += pbc->box[i][j]; } ishift[i]++; } } /* Allow 2 shifts in x */ if (dx[XX] > pbc->hbox_diag[XX]) { dx[XX] -= pbc->fbox_diag[XX]; ishift[XX]--; if (dx[XX] > pbc->hbox_diag[XX]) { dx[XX] -= pbc->fbox_diag[XX]; ishift[XX]--; } } else if (dx[XX] <= pbc->mhbox_diag[XX]) { dx[XX] += pbc->fbox_diag[XX]; ishift[XX]++; if (dx[XX] <= pbc->mhbox_diag[XX]) { dx[XX] += pbc->fbox_diag[XX]; ishift[XX]++; } } /* dx is the distance in a rectangular box */ d2min = norm2(dx); if (d2min > pbc->max_cutoff2) { copy_rvec(dx, dx_start); copy_ivec(ishift, ishift_start); d2min = norm2(dx); /* Now try all possible shifts, when the distance is within max_cutoff * it must be the shortest possible distance. */ i = 0; while ((d2min > pbc->max_cutoff2) && (i < pbc->ntric_vec)) { rvec_add(dx_start, pbc->tric_vec[i], trial); d2trial = norm2(trial); if (d2trial < d2min) { copy_rvec(trial, dx); ivec_add(ishift_start, pbc->tric_shift[i], ishift); d2min = d2trial; } i++; } } break; case epbcdx2D_RECT: for (i = 0; i < DIM; i++) { if (i != pbc->dim) { if (dx[i] > pbc->hbox_diag[i]) { dx[i] -= pbc->fbox_diag[i]; ishift[i]--; } else if (dx[i] <= pbc->mhbox_diag[i]) { dx[i] += pbc->fbox_diag[i]; ishift[i]++; } } } break; case epbcdx2D_TRIC: d2min = 0; for (i = DIM-1; i >= 1; i--) { if (i != pbc->dim) { if (dx[i] > pbc->hbox_diag[i]) { for (j = i; j >= 0; j--) { dx[j] -= pbc->box[i][j]; } ishift[i]--; } else if (dx[i] <= pbc->mhbox_diag[i]) { for (j = i; j >= 0; j--) { dx[j] += pbc->box[i][j]; } ishift[i]++; } d2min += dx[i]*dx[i]; } } if (pbc->dim != XX) { /* Allow 2 shifts in x */ if (dx[XX] > pbc->hbox_diag[XX]) { dx[XX] -= pbc->fbox_diag[XX]; ishift[XX]--; if (dx[XX] > pbc->hbox_diag[XX]) { dx[XX] -= pbc->fbox_diag[XX]; ishift[XX]--; } } else if (dx[XX] <= pbc->mhbox_diag[XX]) { dx[XX] += pbc->fbox_diag[XX]; ishift[XX]++; if (dx[XX] <= pbc->mhbox_diag[XX]) { dx[XX] += pbc->fbox_diag[XX]; ishift[XX]++; } } d2min += dx[XX]*dx[XX]; } if (d2min > pbc->max_cutoff2) { copy_rvec(dx, dx_start); copy_ivec(ishift, ishift_start); /* Now try all possible shifts, when the distance is within max_cutoff * it must be the shortest possible distance. */ i = 0; while ((d2min > pbc->max_cutoff2) && (i < pbc->ntric_vec)) { rvec_add(dx_start, pbc->tric_vec[i], trial); d2trial = 0; for (j = 0; j < DIM; j++) { if (j != pbc->dim) { d2trial += trial[j]*trial[j]; } } if (d2trial < d2min) { copy_rvec(trial, dx); ivec_add(ishift_start, pbc->tric_shift[i], ishift); d2min = d2trial; } i++; } } break; case epbcdx1D_RECT: i = pbc->dim; if (dx[i] > pbc->hbox_diag[i]) { dx[i] -= pbc->fbox_diag[i]; ishift[i]--; } else if (dx[i] <= pbc->mhbox_diag[i]) { dx[i] += pbc->fbox_diag[i]; ishift[i]++; } break; case epbcdx1D_TRIC: i = pbc->dim; if (dx[i] > pbc->hbox_diag[i]) { rvec_dec(dx, pbc->box[i]); ishift[i]--; } else if (dx[i] <= pbc->mhbox_diag[i]) { rvec_inc(dx, pbc->box[i]); ishift[i]++; } break; case epbcdxSCREW_RECT: /* The shift definition requires x first */ if (dx[XX] > pbc->hbox_diag[XX]) { dx[XX] -= pbc->fbox_diag[XX]; ishift[XX]--; } else if (dx[XX] <= pbc->mhbox_diag[XX]) { dx[XX] += pbc->fbox_diag[XX]; ishift[XX]++; } if (ishift[XX] == 1 || ishift[XX] == -1) { /* Rotate around the x-axis in the middle of the box */ dx[YY] = pbc->box[YY][YY] - x1[YY] - x2[YY]; dx[ZZ] = pbc->box[ZZ][ZZ] - x1[ZZ] - x2[ZZ]; } /* Normal pbc for y and z */ for (i = YY; i <= ZZ; i++) { if (dx[i] > pbc->hbox_diag[i]) { dx[i] -= pbc->fbox_diag[i]; ishift[i]--; } else if (dx[i] <= pbc->mhbox_diag[i]) { dx[i] += pbc->fbox_diag[i]; ishift[i]++; } } break; case epbcdxNOPBC: case epbcdxUNSUPPORTED: break; default: gmx_fatal(FARGS, "Internal error in pbc_dx_aiuc, set_pbc_dd or set_pbc has not been called"); break; } is = IVEC2IS(ishift); if (debug) { range_check_mesg(is, 0, SHIFTS, "PBC shift vector index range check."); } return is; }