static bool step_man(t_manager *man, int *nat)
{
    static int      ncount = 0;
    static bool     bWarn  = false;
    bool            bEof;
    const char     *warn;

    if (!man->natom)
    {
        fprintf(stderr, "Not initiated yet!");
        exit(1);
    }
    bEof = read_next_x(man->oenv, man->status, &man->time, man->x, man->box);
    *nat = man->natom;
    if (ncount == man->nSkip)
    {
        switch (man->molw->boxtype)
        {
            case esbTri:
                put_atoms_in_triclinic_unitcell(ecenterDEF, man->box, man->natom, man->x);
                break;
            case esbTrunc:
                warn = put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box,
                                                     man->natom, man->x);
                if (warn && !bWarn)
                {
                    fprintf(stderr, "\n%s\n", warn);
                    bWarn = true;
                }
                break;
            case esbRect:
            case esbNone:
            default:
                break;
        }
        if (man->bPbc)
        {
            gmx_rmpbc(man->gpbc, man->natom, man->box, man->x);
            reset_mols(&(man->top.mols), man->box, man->x);
        }
        ncount = 0;
    }
    else
    {
        if (man->nSkip > 0)
        {
            ncount++;
            return step_man(man, nat);
        }
    }

    return bEof;
}
Exemplo n.º 2
0
static bool step_man(t_manager *man, int *nat)
{
    static int      ncount = 0;
    bool            bEof;

    if (!man->natom)
    {
        std::fprintf(stderr, "Not initiated yet!");
        std::exit(1);
    }
    bEof = read_next_x(man->oenv, man->status, &man->time, man->x, man->box);
    *nat = man->natom;
    if (ncount == man->nSkip)
    {
        auto atomsArrayRef = gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec *>(man->x), man->natom);
        switch (man->molw->boxtype)
        {
            case esbTri:
                put_atoms_in_triclinic_unitcell(ecenterDEF, man->box, atomsArrayRef);
                break;
            case esbTrunc:
                put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box,
                                              atomsArrayRef);
                break;
            case esbRect:
            case esbNone:
            default:
                break;
        }
        if (man->bPbc)
        {
            gmx_rmpbc(man->gpbc, man->natom, man->box, man->x);
            reset_mols(&(man->top.mols), man->box, man->x);
        }
        ncount = 0;
    }
    else
    {
        if (man->nSkip > 0)
        {
            ncount++;
            return step_man(man, nat);
        }
    }

    return bEof;
}
Exemplo n.º 3
0
/*! \brief
 * Initializes a grid search to find reference positions neighboring \p x.
 */
static void
grid_search_start(gmx_ana_nbsearch_t *d, rvec x)
{
    copy_rvec(x, d->xtest);
    if (d->bGrid)
    {
        put_atoms_in_triclinic_unitcell(ecenterTRIC, d->pbc->box, 1, &d->xtest);
        grid_map_onto(d, d->xtest, d->testcell);
        d->prevnbi = 0;
        d->prevcai = -1;
    }
    else
    {
        d->previ = -1;
    }
    d->exclind = 0;
}
Exemplo n.º 4
0
/*!
 * \param[in,out] d   Neighborhood search data structure.
 * \param[in]     pbc PBC information for the frame.
 * \param[in]     n   Number of reference positions for the frame.
 * \param[in]     x   \p n reference positions for the frame.
 * \returns       0 on success.
 *
 * Initializes the data structure \p d such that it can be used to search
 * for the neighbors of \p x.
 */
int
gmx_ana_nbsearch_init(gmx_ana_nbsearch_t *d, t_pbc *pbc, int n, rvec x[])
{
    d->pbc  = pbc;
    d->nref = n;
    if (!pbc)
    {
        d->bGrid = FALSE;
    }
    else if (d->bTryGrid)
    {
        d->bGrid = grid_set_box(d, pbc);
    }
    if (d->bGrid)
    {
        int  i;

        if (!d->xref_alloc)
        {
            snew(d->xref_alloc, d->maxnref);
        }
        d->xref = d->xref_alloc;
        grid_clear_cells(d);

        for (i = 0; i < n; ++i)
        {
            copy_rvec(x[i], d->xref[i]);
        }
        put_atoms_in_triclinic_unitcell(ecenterTRIC, pbc->box, n, d->xref);
        for (i = 0; i < n; ++i)
        {
            ivec refcell;

            grid_map_onto(d, d->xref[i], refcell);
            grid_add_to_cell(d, refcell, i);
        }
    }
    else
    {
        d->xref = x;
    }
    d->refid = NULL;
    return 0;
}
Exemplo n.º 5
0
int nsc_dclm_pbc(const rvec *coords, real *radius, int nat,
                 int  densit, int mode,
                 real *value_of_area, real **at_area,
                 real *value_of_vol,
                 real **lidots, int *nu_dots,
                 atom_id index[], int ePBC, matrix box)
{
    int         iat, i, ii, iii, ix, iy, iz, ixe, ixs, iye, iys, ize, izs, i_ac;
    int         jat, j, jj, jjj, jx, jy, jz;
    int         distribution;
    int         l;
    int         maxnei, nnei, last, maxdots = 0;
    int        *wkdot = NULL, *wkbox = NULL, *wkat1 = NULL, *wkatm = NULL;
    Neighb     *wknb, *ctnb;
    int         iii1, iii2, iiat, lfnr = 0, i_at, j_at;
    real        dx, dy, dz, dd, ai, aisq, ajsq, aj, as, a;
    real        xi, yi, zi, xs = 0., ys = 0., zs = 0.;
    real        dotarea, area, vol = 0.;
    real       *xus, *dots = NULL, *atom_area = NULL;
    int         nxbox, nybox, nzbox, nxy, nxyz;
    real        xmin = 0, ymin = 0, zmin = 0, xmax, ymax, zmax, ra2max, d;
    const real *pco;
    /* Added DvdS 2006-07-19 */
    t_pbc       pbc;
    rvec        ddx, *x = NULL;
    int         iat_xx, jat_xx;

    distribution = unsp_type(densit);
    if (distribution != -last_unsp || last_cubus != 4 ||
        (densit != last_densit && densit != last_n_dot))
    {
        if (make_unsp(densit, (-distribution), &n_dot, 4))
        {
            return 1;
        }
    }
    xus = xpunsp;

    dotarea = FOURPI/(real) n_dot;
    area    = 0.;

    if (debug)
    {
        fprintf(debug, "nsc_dclm: n_dot=%5d %9.3f\n", n_dot, dotarea);
    }

    /* start with neighbour list */
    /* calculate neighbour list with the box algorithm */
    if (nat == 0)
    {
        WARNING("nsc_dclm: no surface atoms selected");
        return 1;
    }
    if (mode & FLAG_VOLUME)
    {
        vol = 0.;
    }
    if (mode & FLAG_DOTS)
    {
        maxdots = (3*n_dot*nat)/10;
        /* should be set to NULL on first user call */
        if (dots == NULL)
        {
            snew(dots, maxdots);
        }
        else
        {
            srenew(dots, maxdots);
        }

        lfnr = 0;
    }
    if (mode & FLAG_ATOM_AREA)
    {
        /* should be set to NULL on first user call */
        if (atom_area == NULL)
        {
            snew(atom_area, nat);
        }
        else
        {
            srenew(atom_area, nat);
        }
    }

    /* Compute minimum size for grid cells */
    ra2max = radius[index[0]];
    for (iat_xx = 1; (iat_xx < nat); iat_xx++)
    {
        iat    = index[iat_xx];
        ra2max = max(ra2max, radius[iat]);
    }
    ra2max = 2*ra2max;

    /* Added DvdS 2006-07-19 */
    /* Updated 2008-10-09 */
    if (box)
    {
        set_pbc(&pbc, ePBC, box);
        snew(x, nat);
        for (i = 0; (i < nat); i++)
        {
            iat  = index[0];
            copy_rvec(coords[iat], x[i]);
        }
        put_atoms_in_triclinic_unitcell(ecenterTRIC, box, nat, x);
        nxbox = max(1, floor(norm(box[XX])/ra2max));
        nybox = max(1, floor(norm(box[YY])/ra2max));
        nzbox = max(1, floor(norm(box[ZZ])/ra2max));
        if (debug)
        {
            fprintf(debug, "nbox = %d, %d, %d\n", nxbox, nybox, nzbox);
        }
    }
    else
    {
        /* dimensions of atomic set, cell edge is 2*ra_max */
        iat    = index[0];
        xmin   = coords[iat][XX]; xmax = xmin; xs = xmin;
        ymin   = coords[iat][YY]; ymax = ymin; ys = ymin;
        zmin   = coords[iat][ZZ]; zmax = zmin; zs = zmin;

        for (iat_xx = 1; (iat_xx < nat); iat_xx++)
        {
            iat  = index[iat_xx];
            pco  = coords[iat];
            xmin = min(xmin, *pco);     xmax = max(xmax, *pco);
            ymin = min(ymin, *(pco+1)); ymax = max(ymax, *(pco+1));
            zmin = min(zmin, *(pco+2)); zmax = max(zmax, *(pco+2));
            xs   = xs+ *pco; ys = ys+ *(pco+1); zs = zs+ *(pco+2);
        }
        xs = xs/ (real) nat;
        ys = ys/ (real) nat;
        zs = zs/ (real) nat;
        if (debug)
        {
            fprintf(debug, "nsc_dclm: n_dot=%5d ra2max=%9.3f %9.3f\n", n_dot, ra2max, dotarea);
        }

        d    = xmax-xmin; nxbox = (int) max(ceil(d/ra2max), 1.);
        d    = (((real)nxbox)*ra2max-d)/2.;
        xmin = xmin-d; xmax = xmax+d;
        d    = ymax-ymin; nybox = (int) max(ceil(d/ra2max), 1.);
        d    = (((real)nybox)*ra2max-d)/2.;
        ymin = ymin-d; ymax = ymax+d;
        d    = zmax-zmin; nzbox = (int) max(ceil(d/ra2max), 1.);
        d    = (((real)nzbox)*ra2max-d)/2.;
        zmin = zmin-d; zmax = zmax+d;
    }
    /* Help variables */
    nxy  = nxbox*nybox;
    nxyz = nxy*nzbox;

    /* box number of atoms */
    snew(wkatm, nat);
    snew(wkat1, nat);
    snew(wkdot, n_dot);
    snew(wkbox, nxyz+1);

    if (box)
    {
        matrix box_1;
        rvec   x_1;
        int    ix, iy, iz, m;
        m_inv(box, box_1);
        for (i = 0; (i < nat); i++)
        {
            mvmul(box_1, x[i], x_1);
            ix = ((int)floor(x_1[XX]*nxbox) + 2*nxbox) % nxbox;
            iy = ((int)floor(x_1[YY]*nybox) + 2*nybox) % nybox;
            iz = ((int)floor(x_1[ZZ]*nzbox) + 2*nzbox) % nzbox;
            j  =  ix + iy*nxbox + iz*nxbox*nybox;
            if (debug)
            {
                fprintf(debug, "Atom %d cell index %d. x = (%8.3f,%8.3f,%8.3f) fc = (%8.3f,%8.3f,%8.3f)\n",
                        i, j, x[i][XX], x[i][YY], x[i][ZZ], x_1[XX], x_1[YY], x_1[ZZ]);
            }
            range_check(j, 0, nxyz);
            wkat1[i] = j;
            wkbox[j]++;
        }
    }
    else
    {
        /* Put the atoms in their boxes */
        for (iat_xx = 0; (iat_xx < nat); iat_xx++)
        {
            iat           = index[iat_xx];
            pco           = coords[iat];
            i             = (int) max(floor((pco[XX]-xmin)/ra2max), 0);
            i             = min(i, nxbox-1);
            j             = (int) max(floor((pco[YY]-ymin)/ra2max), 0);
            j             = min(j, nybox-1);
            l             = (int) max(floor((pco[ZZ]-zmin)/ra2max), 0);
            l             = min(l, nzbox-1);
            i             = i+j*nxbox+l*nxy;
            wkat1[iat_xx] = i;
            wkbox[i]++;
        }
    }

    /* sorting of atoms in accordance with box numbers */
    j = wkbox[0];
    for (i = 1; i < nxyz; i++)
    {
        j = max(wkbox[i], j);
    }
    for (i = 1; i <= nxyz; i++)
    {
        wkbox[i] += wkbox[i-1];
    }

    /* maxnei = (int) floor(ra2max*ra2max*ra2max*0.5); */
    maxnei = min(nat, 27*j);
    snew(wknb, maxnei);
    for (iat_xx = 0; iat_xx < nat; iat_xx++)
    {
        iat = index[iat_xx];
        range_check(wkat1[iat_xx], 0, nxyz);
        wkatm[--wkbox[wkat1[iat_xx]]] = iat_xx;
        if (debug)
        {
            fprintf(debug, "atom %5d on place %5d\n", iat, wkbox[wkat1[iat_xx]]);
        }
    }

    if (debug)
    {
        fprintf(debug, "nsc_dclm: n_dot=%5d ra2max=%9.3f %9.3f\n",
                n_dot, ra2max, dotarea);
        fprintf(debug, "neighbour list calculated/box(xyz):%d %d %d\n",
                nxbox, nybox, nzbox);

        for (i = 0; i < nxyz; i++)
        {
            fprintf(debug, "box %6d : atoms %4d-%4d    %5d\n",
                    i, wkbox[i], wkbox[i+1]-1, wkbox[i+1]-wkbox[i]);
        }
        for (i = 0; i < nat; i++)
        {
            fprintf(debug, "list place %5d by atom %7d\n", i, index[wkatm[i]]);
        }
    }

    /* calculate surface for all atoms, step cube-wise */
    for (iz = 0; iz < nzbox; iz++)
    {
        iii = iz*nxy;
        if (box)
        {
            izs = iz-1;
            ize = min(iz+2, izs+nzbox);
        }
        else
        {
            izs = max(iz-1, 0);
            ize = min(iz+2, nzbox);
        }
        for (iy = 0; iy < nybox; iy++)
        {
            ii = iy*nxbox+iii;
            if (box)
            {
                iys = iy-1;
                iye = min(iy+2, iys+nybox);
            }
            else
            {
                iys = max(iy-1, 0);
                iye = min(iy+2, nybox);
            }
            for (ix = 0; ix < nxbox; ix++)
            {
                i    = ii+ix;
                iii1 = wkbox[i];
                iii2 = wkbox[i+1];
                if (iii1 >= iii2)
                {
                    continue;
                }
                if (box)
                {
                    ixs = ix-1;
                    ixe = min(ix+2, ixs+nxbox);
                }
                else
                {
                    ixs = max(ix-1, 0);
                    ixe = min(ix+2, nxbox);
                }
                iiat = 0;
                /* make intermediate atom list */
                for (jz = izs; jz < ize; jz++)
                {
                    jjj = ((jz+nzbox) % nzbox)*nxy;
                    for (jy = iys; jy < iye; jy++)
                    {
                        jj = ((jy+nybox) % nybox)*nxbox+jjj;
                        for (jx = ixs; jx < ixe; jx++)
                        {
                            j = jj+((jx+nxbox) % nxbox);
                            for (jat = wkbox[j]; jat < wkbox[j+1]; jat++)
                            {
                                range_check(wkatm[jat], 0, nat);
                                range_check(iiat, 0, nat);
                                wkat1[iiat] = wkatm[jat];
                                iiat++;
                            } /* end of cycle "jat" */
                        }     /* end of cycle "jx" */
                    }         /* end of cycle "jy" */
                }             /* end of cycle "jz" */
                for (iat = iii1; iat < iii2; iat++)
                {
                    i_at = index[wkatm[iat]];
                    ai   = radius[i_at];
                    aisq = ai*ai;
                    pco  = coords[i_at];
                    xi   = pco[XX]; yi = pco[YY]; zi = pco[ZZ];
                    for (i = 0; i < n_dot; i++)
                    {
                        wkdot[i] = 0;
                    }

                    ctnb = wknb; nnei = 0;
                    for (j = 0; j < iiat; j++)
                    {
                        j_at = index[wkat1[j]];
                        if (j_at == i_at)
                        {
                            continue;
                        }

                        aj   = radius[j_at];
                        ajsq = aj*aj;
                        pco  = coords[j_at];

                        /* Added DvdS 2006-07-19 */
                        if (box)
                        {
                            /*rvec xxi;

                               xxi[XX] = xi;
                               xxi[YY] = yi;
                               xxi[ZZ] = zi;
                               pbc_dx(&pbc,pco,xxi,ddx);*/
                            pbc_dx(&pbc, coords[j_at], coords[i_at], ddx);
                            dx = ddx[XX];
                            dy = ddx[YY];
                            dz = ddx[ZZ];
                        }
                        else
                        {
                            dx = pco[XX]-xi;
                            dy = pco[YY]-yi;
                            dz = pco[ZZ]-zi;
                        }
                        dd = dx*dx+dy*dy+dz*dz;
                        as = ai+aj;
                        if (dd > as*as)
                        {
                            continue;
                        }
                        nnei++;
                        ctnb->x   = dx;
                        ctnb->y   = dy;
                        ctnb->z   = dz;
                        ctnb->dot = (dd+aisq-ajsq)/(2.*ai); /* reference dot product */
                        ctnb++;
                    }

                    /* check points on accessibility */
                    if (nnei)
                    {
                        last = 0; i_ac = 0;
                        for (l = 0; l < n_dot; l++)
                        {
                            if (xus[3*l]*(wknb+last)->x+
                                xus[1+3*l]*(wknb+last)->y+
                                xus[2+3*l]*(wknb+last)->z <= (wknb+last)->dot)
                            {
                                for (j = 0; j < nnei; j++)
                                {
                                    if (xus[3*l]*(wknb+j)->x+xus[1+3*l]*(wknb+j)->y+
                                        xus[2+3*l]*(wknb+j)->z > (wknb+j)->dot)
                                    {
                                        last = j;
                                        break;
                                    }
                                }
                                if (j >= nnei)
                                {
                                    i_ac++;
                                    wkdot[l] = 1;
                                }
                            } /* end of cycle j */
                        }     /* end of cycle l */
                    }
                    else
                    {
                        i_ac  = n_dot;
                        for (l = 0; l < n_dot; l++)
                        {
                            wkdot[l] = 1;
                        }
                    }

                    if (debug)
                    {
                        fprintf(debug, "i_ac=%d, dotarea=%8.3f, aisq=%8.3f\n",
                                i_ac, dotarea, aisq);
                    }

                    a    = aisq*dotarea* (real) i_ac;
                    area = area + a;
                    if (mode & FLAG_ATOM_AREA)
                    {
                        range_check(wkatm[iat], 0, nat);
                        atom_area[wkatm[iat]] = a;
                    }
                    if (mode & FLAG_DOTS)
                    {
                        for (l = 0; l < n_dot; l++)
                        {
                            if (wkdot[l])
                            {
                                lfnr++;
                                if (maxdots <= 3*lfnr+1)
                                {
                                    maxdots = maxdots+n_dot*3;
                                    srenew(dots, maxdots);
                                }
                                dots[3*lfnr-3] = ai*xus[3*l]+xi;
                                dots[3*lfnr-2] = ai*xus[1+3*l]+yi;
                                dots[3*lfnr-1] = ai*xus[2+3*l]+zi;
                            }
                        }
                    }
                    if (mode & FLAG_VOLUME)
                    {
                        dx = 0.; dy = 0.; dz = 0.;
                        for (l = 0; l < n_dot; l++)
                        {
                            if (wkdot[l])
                            {
                                dx = dx+xus[3*l];
                                dy = dy+xus[1+3*l];
                                dz = dz+xus[2+3*l];
                            }
                        }
                        vol = vol+aisq*(dx*(xi-xs)+dy*(yi-ys)+dz*(zi-zs)+ai* (real) i_ac);
                    }

                } /* end of cycle "iat" */
            }     /* end of cycle "ix" */
        }         /* end of cycle "iy" */
    }             /* end of cycle "iz" */

    sfree(wkatm);
    sfree(wkat1);
    sfree(wkdot);
    sfree(wkbox);
    sfree(wknb);
    if (box)
    {
        sfree(x);
    }
    if (mode & FLAG_VOLUME)
    {
        vol           = vol*FOURPI/(3.* (real) n_dot);
        *value_of_vol = vol;
    }
    if (mode & FLAG_DOTS)
    {
        *nu_dots = lfnr;
        *lidots  = dots;
    }
    if (mode & FLAG_ATOM_AREA)
    {
        *at_area = atom_area;
    }
    *value_of_area = area;

    if (debug)
    {
        fprintf(debug, "area=%8.3f\n", area);
    }

    return 0;
}