Пример #1
0
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;
            }
        }
    }
}
Пример #2
0
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;
            }
        }
    }
}
Пример #3
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;
}
Пример #4
0
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);
                }
            }
        }
    }
}
Пример #5
0
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;
}