Ejemplo n.º 1
0
/* Assemble the positions of the group such that every node has all of them. 
 * The atom indices are retrieved from anrs_loc[0..nr_loc] 
 * Note that coll_ind[i] = i is needed in the serial case */
extern void communicate_group_positions(
        t_commrec  *cr, 
        rvec       *xcoll,        /* OUT: Collective array of positions */
        ivec       *shifts,       /* IN+OUT: Collective array of shifts for xcoll */
        ivec       *extra_shifts, /* BUF: Extra shifts since last time step */
        const gmx_bool bNS,       /* IN:  NS step, the shifts have changed */
        rvec       *x_loc,        /* IN:  Local positions on this node */ 
        const int  nr,            /* IN:  Total number of atoms in the group */
        const int  nr_loc,        /* IN:  Local number of atoms in the group */
        int        *anrs_loc,     /* IN:  Local atom numbers */
        int        *coll_ind,     /* IN:  Collective index */
        rvec       *xcoll_old,    /* IN+OUT: Positions from the last time step, used to make group whole */
        matrix     box)
{
    int i;


    /* Zero out the groups' global position array */
    clear_rvecs(nr, xcoll);

    /* Put the local positions that this node has into the right place of 
     * the collective array. Note that in the serial case, coll_ind[i] = i */
    for (i=0; i<nr_loc; i++)
        copy_rvec(x_loc[anrs_loc[i]], xcoll[coll_ind[i]]);

    if (PAR(cr))
    {
        /* Add the arrays from all nodes together */
        gmx_sum(nr*3, xcoll[0], cr);
    }
    /* To make the group whole, start with a whole group and each
     * step move the assembled positions at closest distance to the positions
     * from the last step. First shift the positions with the saved shift
     * vectors (these are 0 when this routine is called for the first time!) */
    shift_positions_group(box, xcoll, shifts, nr);

    /* Now check if some shifts changed since the last step.
     * This only needs to be done when the shifts are expected to have changed,
     * i.e. after neighboursearching */
    if (bNS)
    {
        get_shifts_group(3, box, xcoll, nr, xcoll_old, extra_shifts);

        /* Shift with the additional shifts such that we get a whole group now */
        shift_positions_group(box, xcoll, extra_shifts, nr);

        /* Add the shift vectors together for the next time step */
        for (i=0; i<nr; i++)
        {
            shifts[i][XX] += extra_shifts[i][XX];
            shifts[i][YY] += extra_shifts[i][YY];
            shifts[i][ZZ] += extra_shifts[i][ZZ];
        }

        /* Store current correctly-shifted positions for comparison in the next NS time step */
        for (i=0; i<nr; i++)
            copy_rvec(xcoll[i],xcoll_old[i]);
    }
}
Ejemplo n.º 2
0
/* Assemble the positions of the group such that every node has all of them.
 * The atom indices are retrieved from anrs_loc[0..nr_loc]
 * Note that coll_ind[i] = i is needed in the serial case */
extern void communicate_group_positions(
        const t_commrec *cr,           /* Pointer to MPI communication data */
        rvec            *xcoll,        /* Collective array of positions */
        ivec            *shifts,       /* Collective array of shifts for xcoll (can be NULL) */
        ivec            *extra_shifts, /* (optional) Extra shifts since last time step */
        const gmx_bool   bNS,          /* (optional) NS step, the shifts have changed */
        const rvec      *x_loc,        /* Local positions on this node */
        const int        nr,           /* Total number of atoms in the group */
        const int        nr_loc,       /* Local number of atoms in the group */
        const int       *anrs_loc,     /* Local atom numbers */
        const int       *coll_ind,     /* Collective index */
        rvec            *xcoll_old,    /* (optional) Positions from the last time step,
                                          used to make group whole */
        const matrix     box)          /* (optional) The box */
{
    int i;


    /* Zero out the groups' global position array */
    clear_rvecs(nr, xcoll);

    /* Put the local positions that this node has into the right place of
     * the collective array. Note that in the serial case, coll_ind[i] = i */
    for (i = 0; i < nr_loc; i++)
    {
        copy_rvec(x_loc[anrs_loc[i]], xcoll[coll_ind[i]]);
    }

    if (PAR(cr))
    {
        /* Add the arrays from all nodes together */
        gmx_sum(nr*3, xcoll[0], cr);
    }
    /* Now we have all the positions of the group in the xcoll array present on all
     * nodes.
     *
     * The rest of the code is for making the group whole again in case atoms changed
     * their PBC representation / crossed a box boundary. We only do that if the
     * shifts array is allocated. */
    if (nullptr != shifts)
    {
        /* To make the group whole, start with a whole group and each
         * step move the assembled positions at closest distance to the positions
         * from the last step. First shift the positions with the saved shift
         * vectors (these are 0 when this routine is called for the first time!) */
        shift_positions_group(box, xcoll, shifts, nr);

        /* Now check if some shifts changed since the last step.
         * This only needs to be done when the shifts are expected to have changed,
         * i.e. after neighbor searching */
        if (bNS)
        {
            get_shifts_group(3, box, xcoll, nr, xcoll_old, extra_shifts);

            /* Shift with the additional shifts such that we get a whole group now */
            shift_positions_group(box, xcoll, extra_shifts, nr);

            /* Add the shift vectors together for the next time step */
            for (i = 0; i < nr; i++)
            {
                shifts[i][XX] += extra_shifts[i][XX];
                shifts[i][YY] += extra_shifts[i][YY];
                shifts[i][ZZ] += extra_shifts[i][ZZ];
            }

            /* Store current correctly-shifted positions for comparison in the next NS time step */
            for (i = 0; i < nr; i++)
            {
                copy_rvec(xcoll[i], xcoll_old[i]);
            }
        }
    }
}