예제 #1
0
static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zslices,
                            int tblocks, real binwidth, int method,
                            real dens1, real dens2, t_interf ****intf1,
                            t_interf ****intf2, const gmx_output_env_t *oenv)
{
    /*Returns two pointers to 3D arrays of t_interf structs containing (position,thickness) of the interface(s)*/
    FILE         *xvg;
    real         *zDensavg; /* zDensavg[z]*/
    int           i, j, k, n;
    int           xysize;
    int           ndx1, ndx2, *zperm;
    real          densmid;
    real          splitpoint, startpoint, endpoint;
    real         *sigma1, *sigma2;
    double        beginfit1[4];
    double        beginfit2[4];
    double       *fit1 = NULL, *fit2 = NULL;
    const double *avgfit1;
    const double *avgfit2;
    const real    onehalf = 1.00/2.00;
    t_interf   ***int1    = NULL, ***int2 = NULL; /*Interface matrices [t][x,y] - last index in row-major order*/
    /*Create int1(t,xy) and int2(t,xy) arrays with correct number of interf_t elements*/
    xysize = xslices*yslices;
    snew(int1, tblocks);
    snew(int2, tblocks);
    for (i = 0; i < tblocks; i++)
    {
        snew(int1[i], xysize);
        snew(int2[i], xysize);
        for (j = 0; j < xysize; j++)
        {
            snew(int1[i][j], 1);
            snew(int2[i][j], 1);
            init_interf(int1[i][j]);
            init_interf(int2[i][j]);
        }
    }

    if (method == methBISECT)
    {
        densmid = onehalf*(dens1+dens2);
        snew(zperm, zslices);
        for (n = 0; n < tblocks; n++)
        {
            for (i = 0; i < xslices; i++)
            {
                for (j = 0; j < yslices; j++)
                {
                    rangeArray(zperm, zslices); /*reset permutation array to identity*/
                    /*Binsearch returns slice-nr where the order param is  <= setpoint sgmid*/
                    ndx1 = start_binsearch(Densmap[n][i][j], zperm, 0, zslices/2-1, densmid, 1);
                    ndx2 = start_binsearch(Densmap[n][i][j], zperm, zslices/2, zslices-1, densmid, -1);

                    /* Linear interpolation (for use later if time allows)
                     * rho_1s= Densmap[n][i][j][zperm[ndx1]]
                     * rho_1e =Densmap[n][i][j][zperm[ndx1+1]] - in worst case might be far off
                     * rho_2s =Densmap[n][i][j][zperm[ndx2+1]]
                     * rho_2e =Densmap[n][i][j][zperm[ndx2]]
                     * For 1st interface we have:
                       densl= Densmap[n][i][j][zperm[ndx1]];
                       densr= Densmap[n][i][j][zperm[ndx1+1]];
                       alpha=(densmid-densl)/(densr-densl);
                       deltandx=zperm[ndx1+1]-zperm[ndx1];

                       if(debug){
                       printf("Alpha, Deltandx  %f %i\n", alpha,deltandx);
                       }
                       if(abs(alpha)>1.0 || abs(deltandx)>3){
                       pos=zperm[ndx1];
                       spread=-1;
                       }
                       else {
                       pos=zperm[ndx1]+alpha*deltandx;
                       spread=binwidth*deltandx;
                       }
                     * For the 2nd interface  can use the same formulation, since alpha should become negative ie:
                     * alpha=(densmid-Densmap[n][i][j][zperm[ndx2]])/(Densmap[n][i][j][zperm[nxd2+1]]-Densmap[n][i][j][zperm[ndx2]]);
                     * deltandx=zperm[ndx2+1]-zperm[ndx2];
                     * pos=zperm[ndx2]+alpha*deltandx;   */

                    /*After filtering we use the direct approach	*/
                    int1[n][j+(i*yslices)]->Z = (zperm[ndx1]+onehalf)*binwidth;
                    int1[n][j+(i*yslices)]->t = binwidth;
                    int2[n][j+(i*yslices)]->Z = (zperm[ndx2]+onehalf)*binwidth;
                    int2[n][j+(i*yslices)]->t = binwidth;
                }
            }
        }
    }

    if (method == methFUNCFIT)
    {
        /*Assume a box divided in 2 along midpoint of z for starters*/
        startpoint = 0.0;
        endpoint   = binwidth*zslices;
        splitpoint = (startpoint+endpoint)/2.0;
        /*Initial fit proposals*/
        beginfit1[0] = dens1;
        beginfit1[1] = dens2;
        beginfit1[2] = (splitpoint/2);
        beginfit1[3] = 0.5;

        beginfit2[0] = dens2;
        beginfit2[1] = dens1;
        beginfit2[2] = (3*splitpoint/2);
        beginfit2[3] = 0.5;

        snew(zDensavg, zslices);
        snew(sigma1, zslices);
        snew(sigma2, zslices);

        for (k = 0; k < zslices; k++)
        {
            sigma1[k] = sigma2[k] = 1;
        }
        /*Calculate average density along z - avoid smoothing by using coarse-grained-mesh*/
        for (k = 0; k < zslices; k++)
        {
            for (n = 0; n < tblocks; n++)
            {
                for (i = 0; i < xslices; i++)
                {
                    for (j = 0; j < yslices; j++)
                    {
                        zDensavg[k] += (Densmap[n][i][j][k]/(xslices*yslices*tblocks));
                    }
                }
            }
        }

        if (debug)
        {
            xvg = xvgropen("DensprofileonZ.xvg", "Averaged Densityprofile on Z", "z[nm]", "Density[kg/m^3]", oenv);
            for (k = 0; k < zslices; k++)
            {
                fprintf(xvg, "%4f.3   %8f.4\n", k*binwidth, zDensavg[k]);
            }
            xvgrclose(xvg);
        }

        /*Fit average density in z over whole trajectory to obtain tentative fit-parameters in fit1 and fit2*/

        /*Fit 1st half of box*/
        do_lmfit(zslices, zDensavg, sigma1, binwidth, NULL, startpoint, splitpoint, oenv, FALSE, effnERF, beginfit1, 8, NULL);
        /*Fit 2nd half of box*/
        do_lmfit(zslices, zDensavg, sigma2, binwidth, NULL, splitpoint, endpoint, oenv, FALSE, effnERF, beginfit2, 8, NULL);

        /*Initialise the const arrays for storing the average fit parameters*/
        avgfit1 = beginfit1;
        avgfit2 = beginfit2;



        /*Now do fit over each x  y and t slice to get Zint(x,y,t) - loop is very large, we potentially should average over time directly*/
        for (n = 0; n < tblocks; n++)
        {
            for (i = 0; i < xslices; i++)
            {
                for (j = 0; j < yslices; j++)
                {
                    /*Reinitialise fit for each mesh-point*/
                    srenew(fit1, 4);
                    srenew(fit2, 4);
                    for (k = 0; k < 4; k++)
                    {
                        fit1[k] = avgfit1[k];
                        fit2[k] = avgfit2[k];
                    }
                    /*Now fit and store in structures in row-major order int[n][i][j]*/
                    do_lmfit(zslices, Densmap[n][i][j], sigma1, binwidth, NULL, startpoint, splitpoint, oenv, FALSE, effnERF, fit1, 0, NULL);
                    int1[n][j+(yslices*i)]->Z = fit1[2];
                    int1[n][j+(yslices*i)]->t = fit1[3];
                    do_lmfit(zslices, Densmap[n][i][j], sigma2, binwidth, NULL, splitpoint, endpoint, oenv, FALSE, effnERF, fit2, 0, NULL);
                    int2[n][j+(yslices*i)]->Z = fit2[2];
                    int2[n][j+(yslices*i)]->t = fit2[3];
                }
            }
        }
    }


    *intf1 = int1;
    *intf2 = int2;

}
예제 #2
0
static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, const char *fnTRX, real binw, int tblock,
                                       int *nframes,  int *nslicex, int *nslicey,
                                       real sgang1, real sgang2, real ****intfpos,
                                       output_env_t oenv)
{
    FILE         *fpsg   = NULL, *fpsk = NULL;
    char         *sgslfn = "sg_ang_mesh";  /* Hardcoded filenames for debugging*/
    char         *skslfn = "sk_dist_mesh";
    t_topology    top;
    int           ePBC;
    char          title[STRLEN], subtitle[STRLEN];
    t_trxstatus  *status;
    int           natoms;
    real          t;
    rvec         *xtop, *x;
    matrix        box;
    real          sg, sk, sgintf, pos;
    atom_id     **index   = NULL;
    char        **grpname = NULL;
    int           i, j, k, n, *isize, ng, nslicez, framenr;
    real       ***sg_grid = NULL, ***sk_grid = NULL, ***sg_fravg = NULL, ***sk_fravg = NULL, ****sk_4d = NULL, ****sg_4d = NULL;
    int          *perm;
    int           ndx1, ndx2;
    int           bins;
    const real    onehalf = 1.0/2.0;
    /* real   ***intfpos[2]; pointers to arrays of two interface positions zcoord(framenr,xbin,ybin): intfpos[interface_index][t][nslicey*x+y]
     * i.e 1D Row-major order in (t,x,y) */


    read_tps_conf(fnTPS, title, &top, &ePBC, &xtop, NULL, box, FALSE);

    *nslicex = (int)(box[XX][XX]/binw + onehalf); /*Calculate slicenr from binwidth*/
    *nslicey = (int)(box[YY][YY]/binw + onehalf);
    nslicez  = (int)(box[ZZ][ZZ]/binw +  onehalf);



    ng = 1;
    /* get index groups */
    printf("Select the group that contains the atoms you want to use for the tetrahedrality order parameter calculation:\n");
    snew(grpname, ng);
    snew(index, ng);
    snew(isize, ng);
    get_index(&top.atoms, fnNDX, ng, isize, index, grpname);

    /* Analyze trajectory */
    natoms = read_first_x(oenv, &status, fnTRX, &t, &x, box);
    if (natoms > top.atoms.nr)
    {
        gmx_fatal(FARGS, "Topology (%d atoms) does not match trajectory (%d atoms)",
                  top.atoms.nr, natoms);
    }
    check_index(NULL, ng, index[0], NULL, natoms);


    /*Prepare structures for temporary storage of frame info*/
    snew(sg_grid, *nslicex);
    snew(sk_grid, *nslicex);
    for (i = 0; i < *nslicex; i++)
    {
        snew(sg_grid[i], *nslicey);
        snew(sk_grid[i], *nslicey);
        for (j = 0; j < *nslicey; j++)
        {
            snew(sg_grid[i][j], nslicez);
            snew(sk_grid[i][j], nslicez);
        }
    }

    sg_4d    = NULL;
    sk_4d    = NULL;
    *nframes = 0;
    framenr  = 0;

/* Loop over frames*/
    do
    {
        /*Initialize box meshes (temporary storage for each tblock frame -reinitialise every tblock steps */
        if (framenr%tblock == 0)
        {
            srenew(sk_4d, *nframes+1);
            srenew(sg_4d, *nframes+1);
            snew(sg_fravg, *nslicex);
            snew(sk_fravg, *nslicex);
            for (i = 0; i < *nslicex; i++)
            {
                snew(sg_fravg[i], *nslicey);
                snew(sk_fravg[i], *nslicey);
                for (j = 0; j < *nslicey; j++)
                {
                    snew(sg_fravg[i][j], nslicez);
                    snew(sk_fravg[i][j], nslicez);
                }
            }
        }

        find_tetra_order_grid(top, ePBC, natoms, box, x, isize[0], index[0], t,
                              &sg, &sk, *nslicex, *nslicey, nslicez, sg_grid, sk_grid);
        for (i = 0; i < *nslicex; i++)
        {
            for (j = 0; j < *nslicey; j++)
            {
                for (k = 0; k < nslicez; k++)
                {
                    sk_fravg[i][j][k] += sk_grid[i][j][k]/tblock;
                    sg_fravg[i][j][k] += sg_grid[i][j][k]/tblock;
                }
            }
        }

        framenr++;

        if (framenr%tblock == 0)
        {
            sk_4d[*nframes] = sk_fravg;
            sg_4d[*nframes] = sg_fravg;
            (*nframes)++;
        }

    }
    while (read_next_x(oenv, status, &t, natoms, x, box));
    close_trj(status);

    sfree(grpname);
    sfree(index);
    sfree(isize);

    /*Debugging for printing out the entire order parameter meshes.*/
    if (debug)
    {
        fpsg = xvgropen(sgslfn, "S\\sg\\N Angle Order Parameter / Meshpoint", "(nm)", "S\\sg\\N", oenv);
        fpsk = xvgropen(skslfn, "S\\sk\\N Distance Order Parameter / Meshpoint", "(nm)", "S\\sk\\N", oenv);
        for (n = 0; n < (*nframes); n++)
        {
            fprintf(fpsg, "%i\n", n);
            fprintf(fpsk, "%i\n", n);
            for (i = 0; (i < *nslicex); i++)
            {
                for (j = 0; j < *nslicey; j++)
                {
                    for (k = 0; k < nslicez; k++)
                    {
                        fprintf(fpsg, "%4f  %4f  %4f  %8f\n", (i+0.5)*box[XX][XX]/(*nslicex), (j+0.5)*box[YY][YY]/(*nslicey), (k+0.5)*box[ZZ][ZZ]/nslicez, sg_4d[n][i][j][k]);
                        fprintf(fpsk, "%4f  %4f  %4f  %8f\n", (i+0.5)*box[XX][XX]/(*nslicex), (j+0.5)*box[YY][YY]/(*nslicey), (k+0.5)*box[ZZ][ZZ]/nslicez, sk_4d[n][i][j][k]);
                    }
                }
            }
        }
        xvgrclose(fpsg);
        xvgrclose(fpsk);
    }


    /* Find positions of interface z by scanning orderparam for each frame and for each xy-mesh cylinder along z*/

    /*Simple trial: assume interface is in the middle of -sgang1 and sgang2*/
    sgintf = 0.5*(sgang1+sgang2);


    /*Allocate memory for interface arrays; */
    snew((*intfpos), 2);
    snew((*intfpos)[0], *nframes);
    snew((*intfpos)[1], *nframes);

    bins = (*nslicex)*(*nslicey);


    snew(perm, nslicez);  /*permutation array for sorting along normal coordinate*/


    for (n = 0; n < *nframes; n++)
    {
        snew((*intfpos)[0][n], bins);
        snew((*intfpos)[1][n], bins);
        for (i = 0; i < *nslicex; i++)
        {
            for (j = 0; j < *nslicey; j++)
            {
                rangeArray(perm, nslicez); /*reset permutation array to identity*/
                /*Binsearch returns 2 bin-numbers where the order param is  <= setpoint sgintf*/
                ndx1 = start_binsearch(sg_4d[n][i][j], perm, 0, nslicez/2-1, sgintf, 1);
                ndx2 = start_binsearch(sg_4d[n][i][j], perm, nslicez/2, nslicez-1, sgintf, -1);
                /*Use linear interpolation to smooth out the interface position*/

                /*left interface (0)*/
                /*if((sg_4d[n][i][j][perm[ndx1+1]]-sg_4d[n][i][j][perm[ndx1]])/sg_4d[n][i][j][perm[ndx1]] > 0.01){
                   pos=( (sgintf-sg_4d[n][i][j][perm[ndx1]])*perm[ndx1+1]+(sg_4d[n][i][j][perm[ndx1+1]]-sgintf)*perm[ndx1 ])*/
                (*intfpos)[0][n][j+*nslicey*i] = (perm[ndx1]+onehalf)*binw;
                /*right interface (1)*/
                /*alpha=(sgintf-sg_4d[n][i][j][perm[ndx2]])/(sg_4d[n][i][j][perm[ndx2]+1]-sg_4d[n][i][j][perm[ndx2]]);*/
                /*(*intfpos)[1][n][j+*nslicey*i]=((1-alpha)*perm[ndx2]+alpha*(perm[ndx2]+1)+onehalf)*box[ZZ][ZZ]/nslicez;*/
                (*intfpos)[1][n][j+*nslicey*i] = (perm[ndx2]+onehalf)*binw;
            }
        }
    }


    /*sfree(perm);*/
    sfree(sk_4d);
    sfree(sg_4d);
    /*sfree(sg_grid);*/
    /*sfree(sk_grid);*/


}