Ejemplo n.º 1
0
static void generate_trial_conf(int atomCount, const rvec xin[],
                                const rvec offset, int enum_rot, gmx_rng_t rng,
                                rvec xout[])
{
    for (int i = 0; i < atomCount; ++i)
    {
        copy_rvec(xin[i], xout[i]);
    }
    real alfa = 0.0, beta = 0.0, gamma = 0.0;
    switch (enum_rot)
    {
        case en_rotXYZ:
            alfa  = 2*M_PI * gmx_rng_uniform_real(rng);
            beta  = 2*M_PI * gmx_rng_uniform_real(rng);
            gamma = 2*M_PI * gmx_rng_uniform_real(rng);
            break;
        case en_rotZ:
            alfa  = beta = 0.;
            gamma = 2*M_PI * gmx_rng_uniform_real(rng);
            break;
        case en_rotNone:
            alfa = beta = gamma = 0.;
            break;
    }
    if (enum_rot == en_rotXYZ || (enum_rot == en_rotZ))
    {
        rotate_conf(atomCount, xout, NULL, alfa, beta, gamma);
    }
    for (int i = 0; i < atomCount; ++i)
    {
        rvec_inc(xout[i], offset);
    }
}
Ejemplo n.º 2
0
static real vrescale_gamdev(int ia, gmx_rng_t rng)
/* Gamma distribution, adapted from numerical recipes */
{
  int j;
  real am,e,s,v1,v2,x,y;
  
  if (ia < 6) {
    x = 1.0;
    for(j=1; j<=ia; j++) {
      x *= gmx_rng_uniform_real(rng);
    }
    x = -log(x);
  } else {
    do {
      do {
        do {
          v1 = gmx_rng_uniform_real(rng);
          v2 = 2.0*gmx_rng_uniform_real(rng)-1.0;
        } while (v1*v1 + v2*v2 > 1.0);
        y = v2/v1;
        am = ia - 1;
        s = sqrt(2.0*am + 1.0);
        x = s*y + am;
      } while (x <= 0.0);
      e = (1.0 + y*y)*exp(am*log(x/am) - s*y);
    } while (gmx_rng_uniform_real(rng) > e);
  }

  return x;
}
Ejemplo n.º 3
0
static real vrescale_gamdev(int ia, gmx_rng_t rng)
/* Gamma distribution, adapted from numerical recipes */
{
    int j;
    real am,e,s,v1,v2,x,y;

    if (ia < 6)
    {
        do
        {
            x = 1.0;
            for(j=1; j<=ia; j++)
            {
                x *= gmx_rng_uniform_real(rng);
            }
        }
        while (x == 0);
        x = -log(x);
    }
    else
    {
        do
        {
            do
            {
                do
                {
                    v1 = gmx_rng_uniform_real(rng);
                    v2 = 2.0*gmx_rng_uniform_real(rng)-1.0;
                }
                while (v1*v1 + v2*v2 > 1.0 ||
                       v1*v1*GMX_REAL_MAX < 3.0*ia);
                /* The last check above ensures that both x (3.0 > 2.0 in s)
                 * and the pre-factor for e do not go out of range.
                 */
                y = v2/v1;
                am = ia - 1;
                s = sqrt(2.0*am + 1.0);
                x = s*y + am;
            }
            while (x <= 0.0);
            e = (1.0 + y*y)*exp(am*log(x/am) - s*y);
        }
        while (gmx_rng_uniform_real(rng) > e);
    }

    return x;
}
Ejemplo n.º 4
0
static void pukeit(const char *db, const char *defstring, char *retstring,
                   int retsize, int *cqnum)
{
    FILE     *fp;
    char    **help;
    int       i, nhlp;
    gmx_rng_t rng;

    if (be_cool() && ((fp = low_libopen(db, FALSE)) != NULL))
    {
        nhlp = fget_lines(fp, &help);
        /* for libraries we can use the low-level close routines */
        gmx_ffclose(fp);
        rng    = gmx_rng_init(gmx_rng_make_seed());
        *cqnum = static_cast<int>(nhlp*gmx_rng_uniform_real(rng));
        gmx_rng_destroy(rng);
        if (strlen(help[*cqnum]) >= STRLEN)
        {
            help[*cqnum][STRLEN-1] = '\0';
        }
        strncpy(retstring, help[*cqnum], retsize);
        for (i = 0; (i < nhlp); i++)
        {
            sfree(help[i]);
        }
        sfree(help);
    }
    else
    {
        *cqnum = -1;
        strncpy(retstring, defstring, retsize);
    }
}
Ejemplo n.º 5
0
static void horizontal()
{
    gmx_rng_t   rng;
    gmx_stats_t straight;
    int         i, ok, n = 1000;
    real        y, a, b, da, db, aver, sigma, error, chi2, R, *xh, *yh;
    FILE       *fp;

    rng      = gmx_rng_init(13);
    straight = gmx_stats_init();
    for (i = 0; (i < n); i++)
    {
        y = gmx_rng_uniform_real(rng);
        if ((ok = gmx_stats_add_point(straight, i, y, 0, 0)) != estatsOK)
        {
            fprintf(stderr, "%s\n", gmx_stats_message(ok));
        }
    }
    /* Horizontal test */
    if ((ok = gmx_stats_get_ase(straight, &aver, &sigma, &error)) != estatsOK)
    {
        fprintf(stderr, "%s\n", gmx_stats_message(ok));
    }
    fp = fopen("straight.xvg", "w");
    if ((ok = gmx_stats_dump_xy(straight, fp)) != estatsOK)
    {
        fprintf(stderr, "%s\n", gmx_stats_message(ok));
    }
    fclose(fp);
    printf("Horizontal line: average %g, sigma %g, error %g\n", aver, sigma, error);
    if ((ok = gmx_stats_done(straight)) != estatsOK)
    {
        fprintf(stderr, "%s\n", gmx_stats_message(ok));
    }
}
Ejemplo n.º 6
0
static void histogram()
{
    gmx_rng_t   rng;
    gmx_stats_t camel;
    int         i, ok, n = 1000, norm;
    real        y, a, b, da, db, aver, sigma, error, chi2, R, *xh, *yh;
    const real  a0 = 0.23, b0 = 2.7;
    FILE       *fp;
    char        fn[256];

    for (norm = 0; (norm < 2); norm++)
    {
        rng      = gmx_rng_init(13);
        camel    = gmx_stats_init();
        for (i = 0; (i < n); i++)
        {
            y = sqr(gmx_rng_uniform_real(rng));
            if ((ok = gmx_stats_add_point(camel, i, y+1, 0, 0)) != estatsOK)
            {
                fprintf(stderr, "%s\n", gmx_stats_message(ok));
            }
            y = sqr(gmx_rng_uniform_real(rng));
            if ((ok = gmx_stats_add_point(camel, i+0.5, y+2, 0, 0)) != estatsOK)
            {
                fprintf(stderr, "%s\n", gmx_stats_message(ok));
            }
        }
        /* Histogram test */
        if ((ok = gmx_stats_make_histogram(camel, 0, 101, norm, &xh, &yh)) != estatsOK)
        {
            fprintf(stderr, "%s\n", gmx_stats_message(ok));
        }
        sprintf(fn, "histo%d-data.xvg", norm);
        fp = fopen(fn, "w");
        gmx_stats_dump_xy(camel, fp);
        fclose(fp);
        sprintf(fn, "histo%d.xvg", norm);
        fp = fopen(fn, "w");
        for (i = 0; (i < 101); i++)
        {
            fprintf(fp, "%12g  %12g\n", xh[i], yh[i]);
        }
        fclose(fp);
        sfree(xh);
        sfree(yh);
    }
}
static void insert_ion(int nsa, int *nwater,
                       gmx_bool bSet[], int repl[], atom_id index[],
                       rvec x[], t_pbc *pbc,
                       int sign, int q, const char *ionname,
                       t_atoms *atoms,
                       real rmin, gmx_rng_t rng)
{
    int             i, ei, nw;
    real            rmin2;
    rvec            dx;
    gmx_int64_t     maxrand;

    ei       = -1;
    nw       = *nwater;
    maxrand  = nw;
    maxrand *= 1000;

    do
    {
        ei = nw*gmx_rng_uniform_real(rng);
        maxrand--;
    }
    while (bSet[ei] && (maxrand > 0));
    if (bSet[ei])
    {
        gmx_fatal(FARGS, "No more replaceable solvent!");
    }

    fprintf(stderr, "Replacing solvent molecule %d (atom %d) with %s\n",
            ei, index[nsa*ei], ionname);

    /* Replace solvent molecule charges with ion charge */
    bSet[ei] = TRUE;
    repl[ei] = sign;

    atoms->atom[index[nsa*ei]].q = q;
    for (i = 1; i < nsa; i++)
    {
        atoms->atom[index[nsa*ei+i]].q = 0;
    }

    /* Mark all solvent molecules within rmin as unavailable for substitution */
    if (rmin > 0)
    {
        rmin2 = rmin*rmin;
        for (i = 0; (i < nw); i++)
        {
            if (!bSet[i])
            {
                pbc_dx(pbc, x[index[nsa*ei]], x[index[nsa*i]], dx);
                if (iprod(dx, dx) < rmin2)
                {
                    bSet[i] = TRUE;
                }
            }
        }
    }
}
Ejemplo n.º 8
0
static void line()
{
    gmx_rng_t   rng;
    gmx_stats_t line;
    int         i, dy, ok, n = 1000;
    real        y, a, b, da, db, aver, sigma, error, chi2, R, rfit;
    const real  a0 = 0.23, b0 = 2.7;
    FILE       *fp;

    for (dy = 0; (dy < 2); dy++)
    {
        rng      = gmx_rng_init(13);
        line     = gmx_stats_init();
        for (i = 0; (i < n); i++)
        {
            y = a0*i+b0+50*(gmx_rng_uniform_real(rng)-0.5);
            if ((ok = gmx_stats_add_point(line, i, y, 0, dy*0.1)) != estatsOK)
            {
                fprintf(stderr, "%s\n", gmx_stats_message(ok));
            }
        }
        /* Line with slope test */
        if ((ok = gmx_stats_get_ab(line, elsqWEIGHT_NONE, &a, &b, &da, &db, &chi2, &rfit)) != estatsOK)
        {
            fprintf(stderr, "%s\n", gmx_stats_message(ok));
        }
        if ((ok = gmx_stats_get_corr_coeff(line, &R)) != estatsOK)
        {
            fprintf(stderr, "%s\n", gmx_stats_message(ok));
        }
        if (dy == 0)
        {
            fp = fopen("line0.xvg", "w");
        }
        else
        {
            fp = fopen("line1.xvg", "w");
        }
        if ((ok = gmx_stats_dump_xy(line, fp)) != estatsOK)
        {
            fprintf(stderr, "%s\n", gmx_stats_message(ok));
        }
        fclose(fp);
        printf("Line with eqn. y = %gx + %g with noise%s\n", a0, b0,
               (dy == 0) ? "" : " and uncertainties");
        printf("Found: a = %g +/- %g, b = %g +/- %g\n", a, da, b, db);
        if ((ok = gmx_stats_done(line)) != estatsOK)
        {
            fprintf(stderr, "%s\n", gmx_stats_message(ok));
        }
        gmx_rng_destroy(rng);
    }
}
Ejemplo n.º 9
0
static void rand_rot(int natoms, rvec x[], rvec v[], vec4 xrot[], vec4 vrot[],
                     gmx_rng_t rng, rvec max_rot)
{
    mat4 mt1, mt2, mr[DIM], mtemp1, mtemp2, mtemp3, mxtot, mvtot;
    rvec xcm;
    real phi;
    int  i, m;

    clear_rvec(xcm);
    for (i = 0; (i < natoms); i++)
    {
        for (m = 0; (m < DIM); m++)
        {
            xcm[m] += x[i][m]/natoms; /* get center of mass of one molecule  */
        }
    }
    fprintf(stderr, "center of geometry: %f, %f, %f\n", xcm[0], xcm[1], xcm[2]);

    /* move c.o.ma to origin */
    gmx_mat4_init_translation(-xcm[XX], -xcm[YY], -xcm[ZZ], mt1);
    for (m = 0; (m < DIM); m++)
    {
        phi = M_PI*max_rot[m]*(2*gmx_rng_uniform_real(rng) - 1)/180;
        gmx_mat4_init_rotation(m, phi, mr[m]);
    }
    gmx_mat4_init_translation(xcm[XX], xcm[YY], xcm[ZZ], mt2);

    /* For gmx_mat4_mmul() we need to multiply in the opposite order
     * compared to normal mathematical notation.
     */
    gmx_mat4_mmul(mtemp1, mt1, mr[XX]);
    gmx_mat4_mmul(mtemp2, mr[YY], mr[ZZ]);
    gmx_mat4_mmul(mtemp3, mtemp1, mtemp2);
    gmx_mat4_mmul(mxtot, mtemp3, mt2);
    gmx_mat4_mmul(mvtot, mr[XX], mtemp2);

    for (i = 0; (i < natoms); i++)
    {
        gmx_mat4_transform_point(mxtot, x[i], xrot[i]);
        gmx_mat4_transform_point(mvtot, v[i], vrot[i]);
    }
}
/* Estimate the reciprocal space part error of the SPME Ewald sum. */
static real estimate_reciprocal(
        t_inputinfo *info, 
        rvec x[],           /* array of particles */
        real q[],           /* array of charges */
        int nr,             /* number of charges = size of the charge array */
        FILE *fp_out,
        gmx_bool bVerbose,
        unsigned int seed,  /* The seed for the random number generator */
        int *nsamples,      /* Return the number of samples used if Monte Carlo
                             * algorithm is used for self energy error estimate */
        t_commrec *cr)
{
    real e_rec=0;   /* reciprocal error estimate */
    real e_rec1=0;  /* Error estimate term 1*/
    real e_rec2=0;  /* Error estimate term 2*/
    real e_rec3=0;  /* Error estimate term 3 */
    real e_rec3x=0; /* part of Error estimate term 3 in x */
    real e_rec3y=0; /* part of Error estimate term 3 in y */
    real e_rec3z=0; /* part of Error estimate term 3 in z */
    int i,ci;
    int nx,ny,nz;   /* grid coordinates */
    real q2_all=0;  /* sum of squared charges */
    rvec gridpx;    /* reciprocal grid point in x direction*/
    rvec gridpxy;   /* reciprocal grid point in x and y direction*/
    rvec gridp;     /* complete reciprocal grid point in 3 directions*/
    rvec tmpvec;    /* template to create points from basis vectors */
    rvec tmpvec2;   /* template to create points from basis vectors */
    real coeff=0;   /* variable to compute coefficients of the error estimate */
    real coeff2=0;   /* variable to compute coefficients of the error estimate */
    real tmp=0;     /* variables to compute different factors from vectors */
    real tmp1=0;
    real tmp2=0;
    gmx_bool bFraction;
    
    /* Random number generator */
    gmx_rng_t rng=NULL;
    int *numbers=NULL;

    /* Index variables for parallel work distribution */
    int startglobal,stopglobal;
    int startlocal, stoplocal;
    int x_per_core;
    int xtot;

#ifdef TAKETIME
    double t0=0.0;
    double t1=0.0;
#endif

    rng=gmx_rng_init(seed);

    clear_rvec(gridpx);
    clear_rvec(gridpxy);
    clear_rvec(gridp);
    clear_rvec(tmpvec);
    clear_rvec(tmpvec2);

    for(i=0;i<nr;i++)
    {
        q2_all += q[i]*q[i];
    }
    
    /* Calculate indices for work distribution */
    startglobal=-info->nkx[0]/2;
    stopglobal = info->nkx[0]/2;
    xtot = stopglobal*2+1;
    if (PAR(cr))
    {
        x_per_core = ceil((real)xtot / (real)cr->nnodes);
        startlocal = startglobal + x_per_core*cr->nodeid;
        stoplocal = startlocal + x_per_core -1;
        if (stoplocal > stopglobal)
             stoplocal = stopglobal;
    }
    else
    {
        startlocal = startglobal;
        stoplocal  = stopglobal;
        x_per_core = xtot;
    }
/*     
#ifdef GMX_LIB_MPI
    MPI_Barrier(MPI_COMM_WORLD);
#endif
*/

#ifdef GMX_LIB_MPI
#ifdef TAKETIME
    if (MASTER(cr))
        t0 = MPI_Wtime();
#endif
#endif
    
    if (MASTER(cr)){
                         
        fprintf(stderr, "Calculating reciprocal error part 1 ...");
        
    }

    for(nx=startlocal; nx<=stoplocal; nx++)
    {   
        svmul(nx,info->recipbox[XX],gridpx);
        for(ny=-info->nky[0]/2; ny<info->nky[0]/2+1; ny++)
        {
            svmul(ny,info->recipbox[YY],tmpvec);
            rvec_add(gridpx,tmpvec,gridpxy);
            for(nz=-info->nkz[0]/2; nz<info->nkz[0]/2+1; nz++)
            {
                if (  0 == nx &&  0 == ny &&  0 == nz )
                    continue;
                svmul(nz,info->recipbox[ZZ],tmpvec);
                rvec_add(gridpxy,tmpvec,gridp);
                tmp=norm2(gridp);
                coeff=exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0] ) ;
                coeff/= 2.0 * M_PI * info->volume * tmp;
                coeff2=tmp ;
                
                
                tmp=eps_poly2(nx,info->nkx[0],info->pme_order[0]);
                tmp+=eps_poly2(ny,info->nkx[0],info->pme_order[0]);
                tmp+=eps_poly2(nz,info->nkx[0],info->pme_order[0]);
                
                tmp1=eps_poly1(nx,info->nkx[0],info->pme_order[0]);
                tmp2=eps_poly1(ny,info->nky[0],info->pme_order[0]);
                
                tmp+=2.0 * tmp1 * tmp2;
                
                tmp1=eps_poly1(nz,info->nkz[0],info->pme_order[0]);
                tmp2=eps_poly1(ny,info->nky[0],info->pme_order[0]);
                
                tmp+=2.0 * tmp1 * tmp2;
                
                tmp1=eps_poly1(nz,info->nkz[0],info->pme_order[0]);
                tmp2=eps_poly1(nx,info->nkx[0],info->pme_order[0]);
                
                tmp+=2.0 * tmp1 * tmp2;
                
                tmp1=eps_poly1(nx,info->nkx[0],info->pme_order[0]);
                tmp1+=eps_poly1(ny,info->nky[0],info->pme_order[0]);
                tmp1+=eps_poly1(nz,info->nkz[0],info->pme_order[0]);
                
                tmp+= tmp1 * tmp1;
                
                e_rec1+= 32.0 * M_PI * M_PI * coeff * coeff * coeff2 * tmp  * q2_all * q2_all / nr ;

                tmp1=eps_poly3(nx,info->nkx[0],info->pme_order[0]);
                tmp1*=info->nkx[0];
                tmp2=iprod(gridp,info->recipbox[XX]);
                
                tmp=tmp1*tmp2;
                
                tmp1=eps_poly3(ny,info->nky[0],info->pme_order[0]);
                tmp1*=info->nky[0];
                tmp2=iprod(gridp,info->recipbox[YY]);
                
                tmp+=tmp1*tmp2;
                
                tmp1=eps_poly3(nz,info->nkz[0],info->pme_order[0]);
                tmp1*=info->nkz[0];
                tmp2=iprod(gridp,info->recipbox[ZZ]);
                
                tmp+=tmp1*tmp2;
                
                tmp*=4.0 * M_PI;
                
                tmp1=eps_poly4(nx,info->nkx[0],info->pme_order[0]);
                tmp1*=norm2(info->recipbox[XX]);
                tmp1*=info->nkx[0] * info->nkx[0];
                
                tmp+=tmp1;
                
                tmp1=eps_poly4(ny,info->nky[0],info->pme_order[0]);
                tmp1*=norm2(info->recipbox[YY]);
                tmp1*=info->nky[0] * info->nky[0];
                
                tmp+=tmp1;
                
                tmp1=eps_poly4(nz,info->nkz[0],info->pme_order[0]);
                tmp1*=norm2(info->recipbox[ZZ]);
                tmp1*=info->nkz[0] * info->nkz[0];
                
                tmp+=tmp1;
                
                e_rec2+= 4.0 * coeff * coeff * tmp * q2_all * q2_all / nr ;
                
            }
        }
        if (MASTER(cr))
            fprintf(stderr, "\rCalculating reciprocal error part 1 ... %3.0f%%", 100.0*(nx-startlocal+1)/(x_per_core));
        
    }

    if (MASTER(cr))
        fprintf(stderr, "\n");
    
    /* Use just a fraction of all charges to estimate the self energy error term? */
    bFraction =  (info->fracself > 0.0) && (info->fracself < 1.0);

    if (bFraction)
    {
        /* Here xtot is the number of samples taken for the Monte Carlo calculation
         * of the average of term IV of equation 35 in Wang2010. Round up to a
         * number of samples that is divisible by the number of nodes */
        x_per_core  = ceil(info->fracself * nr / (real)cr->nnodes);
        xtot = x_per_core * cr->nnodes;
    }
    else
    {
        /* In this case we use all nr particle positions */
        xtot = nr;
        x_per_core = ceil( (real)xtot / (real)cr->nnodes );
    }

    startlocal = x_per_core *  cr->nodeid;
    stoplocal  = min(startlocal + x_per_core, xtot);  /* min needed if xtot == nr */

    if (bFraction)
    {
        /* Make shure we get identical results in serial and parallel. Therefore,
         * take the sample indices from a single, global random number array that
         * is constructed on the master node and that only depends on the seed */
        snew(numbers, xtot);
        if (MASTER(cr))
        {
            for (i=0; i<xtot; i++)
            {
                numbers[i] = floor(gmx_rng_uniform_real(rng) * nr );
            }
        }
        /* Broadcast the random number array to the other nodes */
        if (PAR(cr))
        {
            nblock_bc(cr,xtot,numbers);
        }

        if (bVerbose && MASTER(cr))
        {
            fprintf(stdout, "Using %d sample%s to approximate the self interaction error term",
                    xtot, xtot==1?"":"s");
            if (PAR(cr))
                fprintf(stdout, " (%d sample%s per node)", x_per_core, x_per_core==1?"":"s");
            fprintf(stdout, ".\n");
        }
    }

    /* Return the number of positions used for the Monte Carlo algorithm */
    *nsamples = xtot;

    for(i=startlocal;i<stoplocal;i++)
    {
        e_rec3x=0;
        e_rec3y=0;
        e_rec3z=0;

        if (bFraction)
        {
            /* Randomly pick a charge */
            ci = numbers[i];
        }
        else
        {
            /* Use all charges */
            ci = i;
        }

        /* for(nx=startlocal; nx<=stoplocal; nx++)*/
        for(nx=-info->nkx[0]/2; nx<info->nkx[0]/2+1; nx++) 
        {   
            svmul(nx,info->recipbox[XX],gridpx);
            for(ny=-info->nky[0]/2; ny<info->nky[0]/2+1; ny++)
            {
                svmul(ny,info->recipbox[YY],tmpvec);
                rvec_add(gridpx,tmpvec,gridpxy);
                for(nz=-info->nkz[0]/2; nz<info->nkz[0]/2+1; nz++)
                {
                    
                    if (  0 == nx && 0 == ny && 0 == nz)
                        continue;
                    
                    svmul(nz,info->recipbox[ZZ],tmpvec);
                    rvec_add(gridpxy,tmpvec,gridp);
                    tmp=norm2(gridp);
                    coeff=exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0] );
                    coeff/= tmp ;
                    e_rec3x+=coeff*eps_self(nx,info->nkx[0],info->recipbox[XX],info->pme_order[0],x[ci]);
                    e_rec3y+=coeff*eps_self(ny,info->nky[0],info->recipbox[YY],info->pme_order[0],x[ci]);
                    e_rec3z+=coeff*eps_self(nz,info->nkz[0],info->recipbox[ZZ],info->pme_order[0],x[ci]);

                }
            }
        }

        clear_rvec(tmpvec2);

        svmul(e_rec3x,info->recipbox[XX],tmpvec);
        rvec_inc(tmpvec2,tmpvec);
        svmul(e_rec3y,info->recipbox[YY],tmpvec);
        rvec_inc(tmpvec2,tmpvec);
        svmul(e_rec3z,info->recipbox[ZZ],tmpvec);
        rvec_inc(tmpvec2,tmpvec);

        e_rec3 += q[ci]*q[ci]*q[ci]*q[ci]*norm2(tmpvec2) / ( xtot * M_PI * info->volume * M_PI * info->volume);
        if (MASTER(cr)){
            fprintf(stderr, "\rCalculating reciprocal error part 2 ... %3.0f%%",
                    100.0*(i+1)/stoplocal);

        }
    }

    if (MASTER(cr))
        fprintf(stderr, "\n");

#ifdef GMX_LIB_MPI
#ifdef TAKETIME
    if (MASTER(cr))
    {
        t1= MPI_Wtime() - t0;
        fprintf(fp_out, "Recip. err. est. took   : %lf s\n", t1);
    }
#endif
#endif
   
#ifdef DEBUG
    if (PAR(cr))
    {
        fprintf(stderr, "Node %3d: nx=[%3d...%3d]  e_rec3=%e\n", 
                cr->nodeid, startlocal, stoplocal, e_rec3);
    }
#endif

    if (PAR(cr))
    {
        gmx_sum(1,&e_rec1,cr);
        gmx_sum(1,&e_rec2,cr);
        gmx_sum(1,&e_rec3,cr);
    }
    
    /* e_rec1*=8.0 * q2_all / info->volume / info->volume / nr ;
       e_rec2*=  q2_all / M_PI / M_PI / info->volume / info->volume / nr ;
       e_rec3/= M_PI * M_PI * info->volume * info->volume * nr ; 
     */
    e_rec=sqrt(e_rec1+e_rec2+e_rec3);
    
    
    return ONE_4PI_EPS0 * e_rec;
}
Ejemplo n.º 11
0
gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram (
        gmx_sans_t  *gsans,
        rvec        *x,
        matrix       box,
        atom_id     *index,
        int          isize,
        double       binwidth,
        gmx_bool     bMC,
        gmx_bool     bNORM,
        real         mcover,
        unsigned int seed)
{
    gmx_radial_distribution_histogram_t    *pr = NULL;
    rvec              dist;
    double            rmax;
    int               i, j;
#ifdef GMX_OPENMP
    double          **tgr;
    int               tid;
    int               nthreads;
    gmx_rng_t        *trng = NULL;
#endif
    gmx_large_int_t   mc  = 0, max;
    gmx_rng_t         rng = NULL;

    /* allocate memory for pr */
    snew(pr, 1);
    /* set some fields */
    pr->binwidth = binwidth;

    /*
     * create max dist rvec
     * dist = box[xx] + box[yy] + box[zz]
     */
    rvec_add(box[XX], box[YY], dist);
    rvec_add(box[ZZ], dist, dist);

    rmax = norm(dist);

    pr->grn = (int)floor(rmax/pr->binwidth)+1;
    rmax    = pr->grn*pr->binwidth;

    snew(pr->gr, pr->grn);

    if (bMC)
    {
        /* Special case for setting automaticaly number of mc iterations to 1% of total number of direct iterations */
        if (mcover == -1)
        {
            max = (gmx_large_int_t)floor(0.5*0.01*isize*(isize-1));
        }
        else
        {
            max = (gmx_large_int_t)floor(0.5*mcover*isize*(isize-1));
        }
        rng = gmx_rng_init(seed);
#ifdef GMX_OPENMP
        nthreads = gmx_omp_get_max_threads();
        snew(tgr, nthreads);
        snew(trng, nthreads);
        for (i = 0; i < nthreads; i++)
        {
            snew(tgr[i], pr->grn);
            trng[i] = gmx_rng_init(gmx_rng_uniform_uint32(rng));
        }
        #pragma omp parallel shared(tgr,trng,mc) private(tid,i,j)
        {
            tid = gmx_omp_get_thread_num();
            /* now starting parallel threads */
            #pragma omp for
            for (mc = 0; mc < max; mc++)
            {
                i = (int)floor(gmx_rng_uniform_real(trng[tid])*isize);
                j = (int)floor(gmx_rng_uniform_real(trng[tid])*isize);
                if (i != j)
                {
                    tgr[tid][(int)floor(sqrt(distance2(x[index[i]], x[index[j]]))/binwidth)] += gsans->slength[index[i]]*gsans->slength[index[j]];
                }
            }
        }
        /* collecting data from threads */
        for (i = 0; i < pr->grn; i++)
        {
            for (j = 0; j < nthreads; j++)
            {
                pr->gr[i] += tgr[j][i];
            }
        }
        /* freeing memory for tgr and destroying trng */
        for (i = 0; i < nthreads; i++)
        {
            sfree(tgr[i]);
            gmx_rng_destroy(trng[i]);
        }
        sfree(tgr);
        sfree(trng);
#else
        for (mc = 0; mc < max; mc++)
        {
            i = (int)floor(gmx_rng_uniform_real(rng)*isize);
            j = (int)floor(gmx_rng_uniform_real(rng)*isize);
            if (i != j)
            {
                pr->gr[(int)floor(sqrt(distance2(x[index[i]], x[index[j]]))/binwidth)] += gsans->slength[index[i]]*gsans->slength[index[j]];
            }
        }
#endif
        gmx_rng_destroy(rng);
    }
    else
    {
#ifdef GMX_OPENMP
        nthreads = gmx_omp_get_max_threads();
        /* Allocating memory for tgr arrays */
        snew(tgr, nthreads);
        for (i = 0; i < nthreads; i++)
        {
            snew(tgr[i], pr->grn);
        }
        #pragma omp parallel shared(tgr) private(tid,i,j)
        {
            tid = gmx_omp_get_thread_num();
            /* starting parallel threads */
            #pragma omp for
            for (i = 0; i < isize; i++)
            {
                for (j = 0; j < i; j++)
                {
                    tgr[tid][(int)floor(sqrt(distance2(x[index[i]], x[index[j]]))/binwidth)] += gsans->slength[index[i]]*gsans->slength[index[j]];
                }
            }
        }
        /* collecating data for pr->gr */
        for (i = 0; i < pr->grn; i++)
        {
            for (j = 0; j < nthreads; j++)
            {
                pr->gr[i] += tgr[j][i];
            }
        }
        /* freeing memory for tgr */
        for (i = 0; i < nthreads; i++)
        {
            sfree(tgr[i]);
        }
        sfree(tgr);
#else
        for (i = 0; i < isize; i++)
        {
            for (j = 0; j < i; j++)
            {
                pr->gr[(int)floor(sqrt(distance2(x[index[i]], x[index[j]]))/binwidth)] += gsans->slength[index[i]]*gsans->slength[index[j]];
            }
        }
#endif
    }

    /* normalize if needed */
    if (bNORM)
    {
        normalize_probability(pr->grn, pr->gr);
    }

    snew(pr->r, pr->grn);
    for (i = 0; i < pr->grn; i++)
    {
        pr->r[i] = (pr->binwidth*i+pr->binwidth*0.5);
    }

    return (gmx_radial_distribution_histogram_t *) pr;
}
Ejemplo n.º 12
0
int gmx_nmens(int argc, char *argv[])
{
    const char *desc[] = {
        "[THISMODULE] generates an ensemble around an average structure",
        "in a subspace that is defined by a set of normal modes (eigenvectors).",
        "The eigenvectors are assumed to be mass-weighted.",
        "The position along each eigenvector is randomly taken from a Gaussian",
        "distribution with variance kT/eigenvalue.[PAR]",
        "By default the starting eigenvector is set to 7, since the first six",
        "normal modes are the translational and rotational degrees of freedom."
    };
    static int  nstruct = 100, first = 7, last = -1, seed = -1;
    static real temp    = 300.0;
    t_pargs     pa[]    = {
        { "-temp",  FALSE, etREAL, {&temp},
          "Temperature in Kelvin" },
        { "-seed", FALSE, etINT, {&seed},
          "Random seed, -1 generates a seed from time and pid" },
        { "-num", FALSE, etINT, {&nstruct},
          "Number of structures to generate" },
        { "-first", FALSE, etINT, {&first},
          "First eigenvector to use (-1 is select)" },
        { "-last",  FALSE, etINT, {&last},
          "Last eigenvector to use (-1 is till the last)" }
    };
#define NPA asize(pa)

    t_trxstatus        *out;
    int                 status, trjout;
    t_topology          top;
    int                 ePBC;
    t_atoms            *atoms;
    rvec               *xtop, *xref, *xav, *xout1, *xout2;
    gmx_bool            bDMR, bDMA, bFit;
    int                 nvec, *eignr = NULL;
    rvec              **eigvec = NULL;
    matrix              box;
    real               *eigval, totmass, *invsqrtm, t, disp;
    int                 natoms, neigval;
    char               *grpname, title[STRLEN];
    const char         *indexfile;
    int                 i, j, d, s, v;
    int                 nout, *iout, noutvec, *outvec;
    atom_id            *index;
    real                rfac, invfr, rhalf, jr;
    int          *      eigvalnr;
    output_env_t        oenv;
    gmx_rng_t           rng;
    unsigned long       jran;
    const unsigned long im = 0xffff;
    const unsigned long ia = 1093;
    const unsigned long ic = 18257;


    t_filenm fnm[] = {
        { efTRN, "-v",    "eigenvec",    ffREAD  },
        { efXVG, "-e",    "eigenval",    ffREAD  },
        { efTPS, NULL,    NULL,          ffREAD },
        { efNDX, NULL,    NULL,          ffOPTRD },
        { efTRO, "-o",    "ensemble",    ffWRITE }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_BE_NICE,
                           NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    indexfile = ftp2fn_null(efNDX, NFILE, fnm);

    read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit,
                      &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval);

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xtop, NULL, box, bDMA);
    atoms = &top.atoms;

    printf("\nSelect an index group of %d elements that corresponds to the eigenvectors\n", natoms);
    get_index(atoms, indexfile, 1, &i, &index, &grpname);
    if (i != natoms)
    {
        gmx_fatal(FARGS, "you selected a group with %d elements instead of %d",
                  i, natoms);
    }
    printf("\n");

    snew(invsqrtm, natoms);
    if (bDMA)
    {
        for (i = 0; (i < natoms); i++)
        {
            invsqrtm[i] = gmx_invsqrt(atoms->atom[index[i]].m);
        }
    }
    else
    {
        for (i = 0; (i < natoms); i++)
        {
            invsqrtm[i] = 1.0;
        }
    }

    if (last == -1)
    {
        last = natoms*DIM;
    }
    if (first > -1)
    {
        /* make an index from first to last */
        nout = last-first+1;
        snew(iout, nout);
        for (i = 0; i < nout; i++)
        {
            iout[i] = first-1+i;
        }
    }
    else
    {
        printf("Select eigenvectors for output, end your selection with 0\n");
        nout = -1;
        iout = NULL;
        do
        {
            nout++;
            srenew(iout, nout+1);
            if (1 != scanf("%d", &iout[nout]))
            {
                gmx_fatal(FARGS, "Error reading user input");
            }
            iout[nout]--;
        }
        while (iout[nout] >= 0);
        printf("\n");
    }

    /* make an index of the eigenvectors which are present */
    snew(outvec, nout);
    noutvec = 0;
    for (i = 0; i < nout; i++)
    {
        j = 0;
        while ((j < nvec) && (eignr[j] != iout[i]))
        {
            j++;
        }
        if ((j < nvec) && (eignr[j] == iout[i]))
        {
            outvec[noutvec] = j;
            iout[noutvec]   = iout[i];
            noutvec++;
        }
    }

    fprintf(stderr, "%d eigenvectors selected for output\n", noutvec);

    if (seed == -1)
    {
        seed = (int)gmx_rng_make_seed();
        rng  = gmx_rng_init(seed);
    }
    else
    {
        rng = gmx_rng_init(seed);
    }
    fprintf(stderr, "Using seed %d and a temperature of %g K\n", seed, temp);

    snew(xout1, natoms);
    snew(xout2, atoms->nr);
    out  = open_trx(ftp2fn(efTRO, NFILE, fnm), "w");
    jran = (unsigned long)((real)im*gmx_rng_uniform_real(rng));
    gmx_rng_destroy(rng);
    for (s = 0; s < nstruct; s++)
    {
        for (i = 0; i < natoms; i++)
        {
            copy_rvec(xav[i], xout1[i]);
        }
        for (j = 0; j < noutvec; j++)
        {
            v = outvec[j];
            /* (r-0.5) n times:  var_n = n * var_1 = n/12
               n=4:  var_n = 1/3, so multiply with 3 */

            rfac  = sqrt(3.0 * BOLTZ*temp/eigval[iout[j]]);
            rhalf = 2.0*rfac;
            rfac  = rfac/(real)im;

            jran = (jran*ia+ic) & im;
            jr   = (real)jran;
            jran = (jran*ia+ic) & im;
            jr  += (real)jran;
            jran = (jran*ia+ic) & im;
            jr  += (real)jran;
            jran = (jran*ia+ic) & im;
            jr  += (real)jran;
            disp = rfac * jr - rhalf;

            for (i = 0; i < natoms; i++)
            {
                for (d = 0; d < DIM; d++)
                {
                    xout1[i][d] += disp*eigvec[v][i][d]*invsqrtm[i];
                }
            }
        }
        for (i = 0; i < natoms; i++)
        {
            copy_rvec(xout1[i], xout2[index[i]]);
        }
        t = s+1;
        write_trx(out, natoms, index, atoms, 0, t, box, xout2, NULL, NULL);
        fprintf(stderr, "\rGenerated %d structures", s+1);
    }
    fprintf(stderr, "\n");
    close_trx(out);

    return 0;
}
Ejemplo n.º 13
0
double do_tpi(FILE *fplog,t_commrec *cr,
              int nfile, const t_filenm fnm[],
              const output_env_t oenv, gmx_bool bVerbose,gmx_bool bCompact,
              int nstglobalcomm,
              gmx_vsite_t *vsite,gmx_constr_t constr,
              int stepout,
              t_inputrec *inputrec,
              gmx_mtop_t *top_global,t_fcdata *fcd,
              t_state *state,
              t_mdatoms *mdatoms,
              t_nrnb *nrnb,gmx_wallcycle_t wcycle,
              gmx_edsam_t ed,
              t_forcerec *fr,
              int repl_ex_nst,int repl_ex_seed,
              real cpt_period,real max_hours,
              const char *deviceOptions,
              unsigned long Flags,
              gmx_runtime_t *runtime)
{
  const char *TPI="Test Particle Insertion"; 
  gmx_localtop_t *top;
  gmx_groups_t *groups;
  gmx_enerdata_t *enerd;
  rvec   *f;
  real   lambda,t,temp,beta,drmax,epot;
  double embU,sum_embU,*sum_UgembU,V,V_all,VembU_all;
  t_trxstatus   *status;
  t_trxframe rerun_fr;
  gmx_bool   bDispCorr,bCharge,bRFExcl,bNotLastFrame,bStateChanged,bNS,bOurStep;
  tensor force_vir,shake_vir,vir,pres;
  int    cg_tp,a_tp0,a_tp1,ngid,gid_tp,nener,e;
  rvec   *x_mol;
  rvec   mu_tot,x_init,dx,x_tp;
  int    nnodes,frame,nsteps,step;
  int    i,start,end;
  gmx_rng_t tpi_rand;
  FILE   *fp_tpi=NULL;
  char   *ptr,*dump_pdb,**leg,str[STRLEN],str2[STRLEN];
  double dbl,dump_ener;
  gmx_bool   bCavity;
  int    nat_cavity=0,d;
  real   *mass_cavity=NULL,mass_tot;
  int    nbin;
  double invbinw,*bin,refvolshift,logV,bUlogV;
  real dvdl,prescorr,enercorr,dvdlcorr;
  gmx_bool bEnergyOutOfBounds;
  const char *tpid_leg[2]={"direct","reweighted"};

  /* Since there is no upper limit to the insertion energies,
   * we need to set an upper limit for the distribution output.
   */
  real bU_bin_limit      = 50;
  real bU_logV_bin_limit = bU_bin_limit + 10;

  nnodes = cr->nnodes;

  top = gmx_mtop_generate_local_top(top_global,inputrec);

  groups = &top_global->groups;

  bCavity = (inputrec->eI == eiTPIC);
  if (bCavity) {
    ptr = getenv("GMX_TPIC_MASSES");
    if (ptr == NULL) {
      nat_cavity = 1;
    } else {
      /* Read (multiple) masses from env var GMX_TPIC_MASSES,
       * The center of mass of the last atoms is then used for TPIC.
       */
      nat_cavity = 0;
      while (sscanf(ptr,"%lf%n",&dbl,&i) > 0) {
	srenew(mass_cavity,nat_cavity+1);
	mass_cavity[nat_cavity] = dbl;
	fprintf(fplog,"mass[%d] = %f\n",
		nat_cavity+1,mass_cavity[nat_cavity]);
	nat_cavity++;
	ptr += i;
      }
      if (nat_cavity == 0)
	gmx_fatal(FARGS,"Found %d masses in GMX_TPIC_MASSES",nat_cavity);
    }
  }

  /*
  init_em(fplog,TPI,inputrec,&lambda,nrnb,mu_tot,
  state->box,fr,mdatoms,top,cr,nfile,fnm,NULL,NULL);*/
  /* We never need full pbc for TPI */
  fr->ePBC = epbcXYZ;
  /* Determine the temperature for the Boltzmann weighting */
  temp = inputrec->opts.ref_t[0];
  if (fplog) {
    for(i=1; (i<inputrec->opts.ngtc); i++) {
      if (inputrec->opts.ref_t[i] != temp) {
	fprintf(fplog,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
	fprintf(stderr,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
      }
    }
    fprintf(fplog,
	    "\n  The temperature for test particle insertion is %.3f K\n\n",
	    temp);
  }
  beta = 1.0/(BOLTZ*temp);

  /* Number of insertions per frame */
  nsteps = inputrec->nsteps; 

  /* Use the same neighborlist with more insertions points
   * in a sphere of radius drmax around the initial point
   */
  /* This should be a proper mdp parameter */
  drmax = inputrec->rtpi;

  /* An environment variable can be set to dump all configurations
   * to pdb with an insertion energy <= this value.
   */
  dump_pdb = getenv("GMX_TPI_DUMP");
  dump_ener = 0;
  if (dump_pdb)
    sscanf(dump_pdb,"%lf",&dump_ener);

  atoms2md(top_global,inputrec,0,NULL,0,top_global->natoms,mdatoms);
  update_mdatoms(mdatoms,inputrec->init_lambda);

  snew(enerd,1);
  init_enerdata(groups->grps[egcENER].nr,inputrec->n_flambda,enerd);
  snew(f,top_global->natoms);

  /* Print to log file  */
  runtime_start(runtime);
  print_date_and_time(fplog,cr->nodeid,
                      "Started Test Particle Insertion",runtime); 
  wallcycle_start(wcycle,ewcRUN);

  /* The last charge group is the group to be inserted */
  cg_tp = top->cgs.nr - 1;
  a_tp0 = top->cgs.index[cg_tp];
  a_tp1 = top->cgs.index[cg_tp+1];
  if (debug)
    fprintf(debug,"TPI cg %d, atoms %d-%d\n",cg_tp,a_tp0,a_tp1);
  if (a_tp1 - a_tp0 > 1 &&
      (inputrec->rlist < inputrec->rcoulomb ||
       inputrec->rlist < inputrec->rvdw))
    gmx_fatal(FARGS,"Can not do TPI for multi-atom molecule with a twin-range cut-off");
  snew(x_mol,a_tp1-a_tp0);

  bDispCorr = (inputrec->eDispCorr != edispcNO);
  bCharge = FALSE;
  for(i=a_tp0; i<a_tp1; i++) {
    /* Copy the coordinates of the molecule to be insterted */
    copy_rvec(state->x[i],x_mol[i-a_tp0]);
    /* Check if we need to print electrostatic energies */
    bCharge |= (mdatoms->chargeA[i] != 0 ||
		(mdatoms->chargeB && mdatoms->chargeB[i] != 0));
  }
  bRFExcl = (bCharge && EEL_RF(fr->eeltype) && fr->eeltype!=eelRF_NEC);

  calc_cgcm(fplog,cg_tp,cg_tp+1,&(top->cgs),state->x,fr->cg_cm);
  if (bCavity) {
    if (norm(fr->cg_cm[cg_tp]) > 0.5*inputrec->rlist && fplog) {
      fprintf(fplog, "WARNING: Your TPI molecule is not centered at 0,0,0\n");
      fprintf(stderr,"WARNING: Your TPI molecule is not centered at 0,0,0\n");
    }
  } else {
    /* Center the molecule to be inserted at zero */
     for(i=0; i<a_tp1-a_tp0; i++)
      rvec_dec(x_mol[i],fr->cg_cm[cg_tp]);
  }

  if (fplog) {
    fprintf(fplog,"\nWill insert %d atoms %s partial charges\n",
	    a_tp1-a_tp0,bCharge ? "with" : "without");
    
    fprintf(fplog,"\nWill insert %d times in each frame of %s\n",
	    nsteps,opt2fn("-rerun",nfile,fnm));
  }
  
    if (!bCavity)
    {
        if (inputrec->nstlist > 1)
        {
            if (drmax==0 && a_tp1-a_tp0==1)
            {
                gmx_fatal(FARGS,"Re-using the neighborlist %d times for insertions of a single atom in a sphere of radius %f does not make sense",inputrec->nstlist,drmax);
            }
            if (fplog)
            {
                fprintf(fplog,"Will use the same neighborlist for %d insertions in a sphere of radius %f\n",inputrec->nstlist,drmax);
            }
        }
    }
    else
    {
        if (fplog)
        {
            fprintf(fplog,"Will insert randomly in a sphere of radius %f around the center of the cavity\n",drmax);
        }
    }

  ngid = groups->grps[egcENER].nr;
  gid_tp = GET_CGINFO_GID(fr->cginfo[cg_tp]);
  nener = 1 + ngid;
  if (bDispCorr)
    nener += 1;
  if (bCharge) {
    nener += ngid;
    if (bRFExcl)
      nener += 1;
    if (EEL_FULL(fr->eeltype))
      nener += 1;
  }
  snew(sum_UgembU,nener);

  /* Initialize random generator */
  tpi_rand = gmx_rng_init(inputrec->ld_seed);

  if (MASTER(cr)) {
    fp_tpi = xvgropen(opt2fn("-tpi",nfile,fnm),
		      "TPI energies","Time (ps)",
		      "(kJ mol\\S-1\\N) / (nm\\S3\\N)",oenv);
    xvgr_subtitle(fp_tpi,"f. are averages over one frame",oenv);
    snew(leg,4+nener);
    e = 0;
    sprintf(str,"-kT log(<Ve\\S-\\betaU\\N>/<V>)");
    leg[e++] = strdup(str);
    sprintf(str,"f. -kT log<e\\S-\\betaU\\N>");
    leg[e++] = strdup(str);
    sprintf(str,"f. <e\\S-\\betaU\\N>");
    leg[e++] = strdup(str);
    sprintf(str,"f. V");
    leg[e++] = strdup(str);
    sprintf(str,"f. <Ue\\S-\\betaU\\N>");
    leg[e++] = strdup(str);
    for(i=0; i<ngid; i++) {
      sprintf(str,"f. <U\\sVdW %s\\Ne\\S-\\betaU\\N>",
	      *(groups->grpname[groups->grps[egcENER].nm_ind[i]]));
      leg[e++] = strdup(str);
    }
    if (bDispCorr) {
      sprintf(str,"f. <U\\sdisp c\\Ne\\S-\\betaU\\N>");
      leg[e++] = strdup(str);
    }
    if (bCharge) {
      for(i=0; i<ngid; i++) {
	sprintf(str,"f. <U\\sCoul %s\\Ne\\S-\\betaU\\N>",
		*(groups->grpname[groups->grps[egcENER].nm_ind[i]]));
	leg[e++] = strdup(str);
      }
      if (bRFExcl) {
	sprintf(str,"f. <U\\sRF excl\\Ne\\S-\\betaU\\N>");
	leg[e++] = strdup(str);
      }
      if (EEL_FULL(fr->eeltype)) {
	sprintf(str,"f. <U\\sCoul recip\\Ne\\S-\\betaU\\N>");
	leg[e++] = strdup(str);
      }
    }
    xvgr_legend(fp_tpi,4+nener,(const char**)leg,oenv);
    for(i=0; i<4+nener; i++)
      sfree(leg[i]);
    sfree(leg);
  }
  clear_rvec(x_init);
  V_all = 0;
  VembU_all = 0;

  invbinw = 10;
  nbin = 10;
  snew(bin,nbin);

  bNotLastFrame = read_first_frame(oenv,&status,opt2fn("-rerun",nfile,fnm),
				   &rerun_fr,TRX_NEED_X);
  frame = 0;

  if (rerun_fr.natoms - (bCavity ? nat_cavity : 0) !=
      mdatoms->nr - (a_tp1 - a_tp0))
    gmx_fatal(FARGS,"Number of atoms in trajectory (%d)%s "
	      "is not equal the number in the run input file (%d) "
	      "minus the number of atoms to insert (%d)\n",
	      rerun_fr.natoms,bCavity ? " minus one" : "",
	      mdatoms->nr,a_tp1-a_tp0);

  refvolshift = log(det(rerun_fr.box));

#if ( defined(GMX_IA32_SSE) || defined(GMX_X86_64_SSE) || defined(GMX_X86_64_SSE2) )
    /* Make sure we don't detect SSE overflow generated before this point */
    gmx_mm_check_and_reset_overflow();
#endif

    while (bNotLastFrame)
    {
        lambda = rerun_fr.lambda;
        t = rerun_fr.time;
        
        sum_embU = 0;
        for(e=0; e<nener; e++)
        {
            sum_UgembU[e] = 0;
        }
        
        /* Copy the coordinates from the input trajectory */
        for(i=0; i<rerun_fr.natoms; i++)
        {
            copy_rvec(rerun_fr.x[i],state->x[i]);
        }
        
        V = det(rerun_fr.box);
        logV = log(V);
        
        bStateChanged = TRUE;
        bNS = TRUE;
        for(step=0; step<nsteps; step++)
        {
            /* In parallel all nodes generate all random configurations.
             * In that way the result is identical to a single cpu tpi run.
             */
            if (!bCavity)
            {
                /* Random insertion in the whole volume */
                bNS = (step % inputrec->nstlist == 0);
                if (bNS)
                {
                    /* Generate a random position in the box */
                    x_init[XX] = gmx_rng_uniform_real(tpi_rand)*state->box[XX][XX];
                    x_init[YY] = gmx_rng_uniform_real(tpi_rand)*state->box[YY][YY];
                    x_init[ZZ] = gmx_rng_uniform_real(tpi_rand)*state->box[ZZ][ZZ];
                }
                if (inputrec->nstlist == 1)
                {
                    copy_rvec(x_init,x_tp);
                }
                else
                {
                    /* Generate coordinates within |dx|=drmax of x_init */
                    do
                    {
                        dx[XX] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
                        dx[YY] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
                        dx[ZZ] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
                    }
                    while (norm2(dx) > drmax*drmax);
                    rvec_add(x_init,dx,x_tp);
                }
            }
            else
            {
                /* Random insertion around a cavity location
                 * given by the last coordinate of the trajectory.
                 */
                if (step == 0)
                {
                    if (nat_cavity == 1)
                    {
                        /* Copy the location of the cavity */
                        copy_rvec(rerun_fr.x[rerun_fr.natoms-1],x_init);
                    }
                    else
                    {
                        /* Determine the center of mass of the last molecule */
                        clear_rvec(x_init);
                        mass_tot = 0;
                        for(i=0; i<nat_cavity; i++)
                        {
                            for(d=0; d<DIM; d++)
                            {
                                x_init[d] +=
                                    mass_cavity[i]*rerun_fr.x[rerun_fr.natoms-nat_cavity+i][d];
                            }
                            mass_tot += mass_cavity[i];
                        }
                        for(d=0; d<DIM; d++)
                        {
                            x_init[d] /= mass_tot;
                        }
                    }
                }
                /* Generate coordinates within |dx|=drmax of x_init */
                do
                {
                    dx[XX] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
                    dx[YY] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
                    dx[ZZ] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
                }
                while (norm2(dx) > drmax*drmax);
                rvec_add(x_init,dx,x_tp);
            }
            
            if (a_tp1 - a_tp0 == 1)
            {
                /* Insert a single atom, just copy the insertion location */
	copy_rvec(x_tp,state->x[a_tp0]);
            }
            else
            {
                /* Copy the coordinates from the top file */
                for(i=a_tp0; i<a_tp1; i++)
                {
                    copy_rvec(x_mol[i-a_tp0],state->x[i]);
                }
                /* Rotate the molecule randomly */
                rotate_conf(a_tp1-a_tp0,state->x+a_tp0,NULL,
                            2*M_PI*gmx_rng_uniform_real(tpi_rand),
                            2*M_PI*gmx_rng_uniform_real(tpi_rand),
                            2*M_PI*gmx_rng_uniform_real(tpi_rand));
                /* Shift to the insertion location */
                for(i=a_tp0; i<a_tp1; i++)
                {
                    rvec_inc(state->x[i],x_tp);
                }
            }
            
            /* Check if this insertion belongs to this node */
            bOurStep = TRUE;
            if (PAR(cr))
            {
                switch (inputrec->eI)
                {
                case eiTPI:
                    bOurStep = ((step / inputrec->nstlist) % nnodes == cr->nodeid);
                    break;
                case eiTPIC:
                    bOurStep = (step % nnodes == cr->nodeid);
                    break;
                default:
                    gmx_fatal(FARGS,"Unknown integrator %s",ei_names[inputrec->eI]);
                }
            }
            if (bOurStep)
            {
                /* Clear some matrix variables  */
                clear_mat(force_vir); 
                clear_mat(shake_vir);
                clear_mat(vir);
                clear_mat(pres);
                
                /* Set the charge group center of mass of the test particle */
                copy_rvec(x_init,fr->cg_cm[top->cgs.nr-1]);
                
                /* Calc energy (no forces) on new positions.
                 * Since we only need the intermolecular energy
                 * and the RF exclusion terms of the inserted molecule occur
                 * within a single charge group we can pass NULL for the graph.
                 * This also avoids shifts that would move charge groups
                 * out of the box.
                 *
                 * Some checks above ensure than we can not have
                 * twin-range interactions together with nstlist > 1,
                 * therefore we do not need to remember the LR energies.
                 */
                /* Make do_force do a single node force calculation */
                cr->nnodes = 1;
                do_force(fplog,cr,inputrec,
                         step,nrnb,wcycle,top,top_global,&top_global->groups,
                         rerun_fr.box,state->x,&state->hist,
                         f,force_vir,mdatoms,enerd,fcd,
                         lambda,NULL,fr,NULL,mu_tot,t,NULL,NULL,FALSE,
                         GMX_FORCE_NONBONDED |
                         (bNS ? GMX_FORCE_NS | GMX_FORCE_DOLR : 0) |
                         (bStateChanged ? GMX_FORCE_STATECHANGED : 0)); 
                cr->nnodes = nnodes;
                bStateChanged = FALSE;
                bNS = FALSE;
                
                /* Calculate long range corrections to pressure and energy */
                calc_dispcorr(fplog,inputrec,fr,step,top_global->natoms,rerun_fr.box,
                              lambda,pres,vir,&prescorr,&enercorr,&dvdlcorr);
                /* figure out how to rearrange the next 4 lines MRS 8/4/2009 */
                enerd->term[F_DISPCORR] = enercorr;
                enerd->term[F_EPOT] += enercorr;
                enerd->term[F_PRES] += prescorr;
                enerd->term[F_DVDL] += dvdlcorr;

                epot = enerd->term[F_EPOT];
                bEnergyOutOfBounds = FALSE;
#if ( defined(GMX_IA32_SSE) || defined(GMX_X86_64_SSE) || defined(GMX_X86_64_SSE2) )
                /* With SSE the energy can overflow, check for this */
                if (gmx_mm_check_and_reset_overflow())
                {
                    if (debug)
                    {
                        fprintf(debug,"Found an SSE overflow, assuming the energy is out of bounds\n");
                    }
                    bEnergyOutOfBounds = TRUE;
                }
#endif
                /* If the compiler doesn't optimize this check away
                 * we catch the NAN energies.
                 * The epot>GMX_REAL_MAX check catches inf values,
                 * which should nicely result in embU=0 through the exp below,
                 * but it does not hurt to check anyhow.
                 */
                /* Non-bonded Interaction usually diverge at r=0.
                 * With tabulated interaction functions the first few entries
                 * should be capped in a consistent fashion between
                 * repulsion, dispersion and Coulomb to avoid accidental
                 * negative values in the total energy.
                 * The table generation code in tables.c does this.
                 * With user tbales the user should take care of this.
                 */
                if (epot != epot || epot > GMX_REAL_MAX)
                {
                    bEnergyOutOfBounds = TRUE;
                }
                if (bEnergyOutOfBounds)
                {
                    if (debug)
                    {
                        fprintf(debug,"\n  time %.3f, step %d: non-finite energy %f, using exp(-bU)=0\n",t,step,epot);
                    }
                    embU = 0;
                }
                else
                {
                    embU = exp(-beta*epot);
                    sum_embU += embU;
                    /* Determine the weighted energy contributions of each energy group */
                    e = 0;
                    sum_UgembU[e++] += epot*embU;
                    if (fr->bBHAM)
                    {
                        for(i=0; i<ngid; i++)
                        {
                            sum_UgembU[e++] +=
                                (enerd->grpp.ener[egBHAMSR][GID(i,gid_tp,ngid)] +
                                 enerd->grpp.ener[egBHAMLR][GID(i,gid_tp,ngid)])*embU;
                        }
                    }
                    else
                    {
                        for(i=0; i<ngid; i++)
                        {
                            sum_UgembU[e++] +=
                                (enerd->grpp.ener[egLJSR][GID(i,gid_tp,ngid)] +
                                 enerd->grpp.ener[egLJLR][GID(i,gid_tp,ngid)])*embU;
                        }
                    }
                    if (bDispCorr)
                    {
                        sum_UgembU[e++] += enerd->term[F_DISPCORR]*embU;
                    }
                    if (bCharge)
                    {
                        for(i=0; i<ngid; i++)
                        {
                            sum_UgembU[e++] +=
                                (enerd->grpp.ener[egCOULSR][GID(i,gid_tp,ngid)] +
                                 enerd->grpp.ener[egCOULLR][GID(i,gid_tp,ngid)])*embU;
                        }
                        if (bRFExcl)
                        {
                            sum_UgembU[e++] += enerd->term[F_RF_EXCL]*embU;
                        }
                        if (EEL_FULL(fr->eeltype))
                        {
                            sum_UgembU[e++] += enerd->term[F_COUL_RECIP]*embU;
                        }
                    }
                }
                
                if (embU == 0 || beta*epot > bU_bin_limit)
                {
                    bin[0]++;
                }
                else
                {
                    i = (int)((bU_logV_bin_limit
                               - (beta*epot - logV + refvolshift))*invbinw
                              + 0.5);
                    if (i < 0)
                    {
                        i = 0;
                    }
                    if (i >= nbin)
                    {
                        realloc_bins(&bin,&nbin,i+10);
                    }
                    bin[i]++;
                }

                if(fr->adress_do_drift ||fr->adress_icor == eAdressICThermoForce ){
                    sum_UgembU[e++] += enerd->term[F_ADR_DELTU]*embU;
                }

                if (debug)
                {
                    fprintf(debug,"TPI %7d %12.5e %12.5f %12.5f %12.5f\n",
                            step,epot,x_tp[XX],x_tp[YY],x_tp[ZZ]);
                }

                if (dump_pdb && epot <= dump_ener)
                {
                    sprintf(str,"t%g_step%d.pdb",t,step);
                    sprintf(str2,"t: %f step %d ener: %f",t,step,epot);
                    write_sto_conf_mtop(str,str2,top_global,state->x,state->v,
                                        inputrec->ePBC,state->box);
                }
            }
        }
        
        if (PAR(cr))
        {
            /* When running in parallel sum the energies over the processes */
            gmx_sumd(1,    &sum_embU, cr);
            gmx_sumd(nener,sum_UgembU,cr);
        }

        frame++;
        V_all += V;
        VembU_all += V*sum_embU/nsteps;
        
        if (fp_tpi)
        {
            if (bVerbose || frame%10==0 || frame<10)
            {
                fprintf(stderr,"mu %10.3e <mu> %10.3e\n",
                        -log(sum_embU/nsteps)/beta,-log(VembU_all/V_all)/beta);
            }
            
            fprintf(fp_tpi,"%10.3f %12.5e %12.5e %12.5e %12.5e",
                    t,
                    VembU_all==0 ? 20/beta : -log(VembU_all/V_all)/beta,
                    sum_embU==0  ? 20/beta : -log(sum_embU/nsteps)/beta,
                    sum_embU/nsteps,V);
            for(e=0; e<nener; e++)
            {
                fprintf(fp_tpi," %12.5e",sum_UgembU[e]/nsteps);
            }
            fprintf(fp_tpi,"\n");
            fflush(fp_tpi);
        }
        
        bNotLastFrame = read_next_frame(oenv, status,&rerun_fr);
    } /* End of the loop  */
    runtime_end(runtime);

    close_trj(status);

    if (fp_tpi != NULL)
    {
        gmx_fio_fclose(fp_tpi);
    }

    if (fplog != NULL)
    {
        fprintf(fplog,"\n");
        fprintf(fplog,"  <V>  = %12.5e nm^3\n",V_all/frame);
        fprintf(fplog,"  <mu> = %12.5e kJ/mol\n",-log(VembU_all/V_all)/beta);
    }
  
    /* Write the Boltzmann factor histogram */
    if (PAR(cr))
    {
        /* When running in parallel sum the bins over the processes */
        i = nbin;
        global_max(cr,&i);
        realloc_bins(&bin,&nbin,i);
        gmx_sumd(nbin,bin,cr);
    }
    if (MASTER(cr))
    {
        fp_tpi = xvgropen(opt2fn("-tpid",nfile,fnm),
                          "TPI energy distribution",
                          "\\betaU - log(V/<V>)","count",oenv);
        sprintf(str,"number \\betaU > %g: %9.3e",bU_bin_limit,bin[0]);
        xvgr_subtitle(fp_tpi,str,oenv);
        xvgr_legend(fp_tpi,2,(const char **)tpid_leg,oenv);
        for(i=nbin-1; i>0; i--)
        {
            bUlogV = -i/invbinw + bU_logV_bin_limit - refvolshift + log(V_all/frame);
            fprintf(fp_tpi,"%6.2f %10d %12.5e\n",
                    bUlogV,
                    (int)(bin[i]+0.5),
                    bin[i]*exp(-bUlogV)*V_all/VembU_all);
        }
        gmx_fio_fclose(fp_tpi);
    }
    sfree(bin);

    sfree(sum_UgembU);

    runtime->nsteps_done = frame*inputrec->nsteps;

    return 0;
}
Ejemplo n.º 14
0
/* Estimate the reciprocal space part error of the SPME Ewald sum. */
static real estimate_reciprocal(
        t_inputinfo *info, 
        rvec x[],           /* array of particles */
        real q[],           /* array of charges */
        int nr,             /* number of charges = size of the charge array */
        FILE *fp_out,
        t_commrec *cr)
{
    real e_rec=0;   /* reciprocal error estimate */
    real e_rec1=0;  /* Error estimate term 1*/
    real e_rec2=0;  /* Error estimate term 2*/
    real e_rec3=0;  /* Error estimate term 3 */
    real e_rec3x=0; /* part of Error estimate term 3 in x */
    real e_rec3y=0; /* part of Error estimate term 3 in y */
    real e_rec3z=0; /* part of Error estimate term 3 in z */
    int i,ci;
    int nx,ny,nz;   /* grid coordinates */
    real q2_all=0;  /* sum of squared charges */
    rvec gridpx;    /* reciprocal grid point in x direction*/
    rvec gridpxy;   /* reciprocal grid point in x and y direction*/
    rvec gridp;     /* complete reciprocal grid point in 3 directions*/
    rvec tmpvec;    /* template to create points from basis vectors */
    rvec tmpvec2;   /* template to create points from basis vectors */
    real coeff=0;   /* variable to compute coefficients of the error estimate */
    real coeff2=0;   /* variable to compute coefficients of the error estimate */
    real tmp=0;     /* variables to compute different factors from vectors */
    real tmp1=0;
    real tmp2=0;
    real xtmp=0;
    real ytmp=0;
    real ztmp=0;
    double ewald_error;
    
    /* Random number generator */
    
    gmx_rng_t rng=NULL;
    /*rng=gmx_rng_init(gmx_rng_make_seed());  */

    /* Index variables for parallel work distribution */
    int startglobal,stopglobal;
    int startlocal, stoplocal;
    int x_per_core;
    int nrsamples;
    real xtot;    

/* #define TAKETIME */
#ifdef TAKETIME
    double t0=0.0;
    double t1=0.0;
    double t2=0.0;
#endif

    rng=gmx_rng_init(cr->nodeid);

    clear_rvec(gridpx);
    clear_rvec(gridpxy);
    clear_rvec(gridp);
    clear_rvec(tmpvec);
    clear_rvec(tmpvec2);

    for(i=0;i<nr;i++)
    {
        q2_all += q[i]*q[i];
    }
    
    /* Calculate indices for work distribution */
    startglobal=-info->nkx[0]/2;
    stopglobal = info->nkx[0]/2;
    xtot = stopglobal*2+1;
    if (PAR(cr))
    {
        x_per_core = ceil(xtot / cr->nnodes);
        startlocal = startglobal + x_per_core*cr->nodeid;
        stoplocal = startlocal + x_per_core -1;
        if (stoplocal > stopglobal)
             stoplocal = stopglobal;
    }
    else
    {
        startlocal = startglobal;
        stoplocal  = stopglobal;
        x_per_core = xtot;
    }
/*     
#ifdef GMX_MPI
    MPI_Barrier(MPI_COMM_WORLD);
#endif
*/

#ifdef TAKETIME
    if (MASTER(cr))
        t0 = MPI_Wtime();
#endif
    
    if (MASTER(cr)){
                         
        fprintf(stderr, "Calculating reciprocal error part 1 ...");
        
    }

    for(nx=startlocal; nx<=stoplocal; nx++)
    {   
        svmul(nx,info->recipbox[XX],gridpx);
        for(ny=-info->nky[0]/2; ny<info->nky[0]/2+1; ny++)
        {
            svmul(ny,info->recipbox[YY],tmpvec);
            rvec_add(gridpx,tmpvec,gridpxy);
            for(nz=-info->nkz[0]/2; nz<info->nkz[0]/2+1; nz++)
            {
                if (  0 == nx &&  0 == ny &&  0 == nz )
                    continue;
                svmul(nz,info->recipbox[ZZ],tmpvec);
                rvec_add(gridpxy,tmpvec,gridp);
                tmp=norm2(gridp);
                coeff=exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0] ) ;
                coeff/= 2.0 * M_PI * info->volume * tmp;
                coeff2=tmp ;
                
                
                tmp=eps_poly2(nx,info->nkx[0],info->pme_order[0]);
                tmp+=eps_poly2(ny,info->nkx[0],info->pme_order[0]);
                tmp+=eps_poly2(nz,info->nkx[0],info->pme_order[0]);
                
                tmp1=eps_poly1(nx,info->nkx[0],info->pme_order[0]);
                tmp2=eps_poly1(ny,info->nky[0],info->pme_order[0]);
                
                tmp+=2.0 * tmp1 * tmp2;
                
                tmp1=eps_poly1(nz,info->nkz[0],info->pme_order[0]);
                tmp2=eps_poly1(ny,info->nky[0],info->pme_order[0]);
                
                tmp+=2.0 * tmp1 * tmp2;
                
                tmp1=eps_poly1(nz,info->nkz[0],info->pme_order[0]);
                tmp2=eps_poly1(nx,info->nkx[0],info->pme_order[0]);
                
                tmp+=2.0 * tmp1 * tmp2;
                
                tmp1=eps_poly1(nx,info->nkx[0],info->pme_order[0]);
                tmp1+=eps_poly1(ny,info->nky[0],info->pme_order[0]);
                tmp1+=eps_poly1(nz,info->nkz[0],info->pme_order[0]);
                
                tmp+= tmp1 * tmp1;
                
                e_rec1+= 32.0 * M_PI * M_PI * coeff * coeff * coeff2 * tmp  * q2_all * q2_all / nr ;

                tmp1=eps_poly3(nx,info->nkx[0],info->pme_order[0]);
                tmp1*=info->nkx[0];
                tmp2=iprod(gridp,info->recipbox[XX]);
                
                tmp=tmp1*tmp2;
                
                tmp1=eps_poly3(ny,info->nky[0],info->pme_order[0]);
                tmp1*=info->nky[0];
                tmp2=iprod(gridp,info->recipbox[YY]);
                
                tmp+=tmp1*tmp2;
                
                tmp1=eps_poly3(nz,info->nkz[0],info->pme_order[0]);
                tmp1*=info->nkz[0];
                tmp2=iprod(gridp,info->recipbox[ZZ]);
                
                tmp+=tmp1*tmp2;
                
                tmp*=4.0 * M_PI;
                
                tmp1=eps_poly4(nx,info->nkx[0],info->pme_order[0]);
                tmp1*=norm2(info->recipbox[XX]);
                tmp1*=info->nkx[0] * info->nkx[0];
                
                tmp+=tmp1;
                
                tmp1=eps_poly4(ny,info->nky[0],info->pme_order[0]);
                tmp1*=norm2(info->recipbox[YY]);
                tmp1*=info->nky[0] * info->nky[0];
                
                tmp+=tmp1;
                
                tmp1=eps_poly4(nz,info->nkz[0],info->pme_order[0]);
                tmp1*=norm2(info->recipbox[ZZ]);
                tmp1*=info->nkz[0] * info->nkz[0];
                
                tmp+=tmp1;
                
                e_rec2+= 4.0 * coeff * coeff * tmp * q2_all * q2_all / nr ;
                
            }
        }
        if (MASTER(cr))
            fprintf(stderr, "\rCalculating reciprocal error part 1 ... %3.0f%%", 100.0*(nx-startlocal+1)/(x_per_core));
        
    }

/* 
#ifdef GMX_MPI
    MPI_Barrier(MPI_COMM_WORLD);
#endif
*/

    if (MASTER(cr))
        fprintf(stderr, "\n");
    if (info->fracself>0)
    {
        nrsamples=ceil(info->fracself*nr);
    }
    else
    {
        nrsamples=nr;
    }
    
    
    xtot=nrsamples;


    startglobal=0;
    stopglobal=nr;

    if(PAR(cr))
    {
        x_per_core=ceil(xtot/cr->nnodes);
        startlocal=startglobal+x_per_core*cr->nodeid;
        stoplocal=startglobal+x_per_core*(cr->nodeid+1);
        if (stoplocal>stopglobal)
            stoplocal=stopglobal;
    }
    else
    {
        startlocal=startglobal;
        stoplocal=stopglobal;
        x_per_core=xtot;
    }



    for(i=startlocal;i<stoplocal;i++)
    {
        e_rec3x=0;
        e_rec3y=0;
        e_rec3z=0;

        if (info->fracself<0) {
            ci=i;
        }else {
            ci=floor(gmx_rng_uniform_real(rng) * nr );
            if (ci==nr)
            {
                ci=nr-1;
            }
        }

        /* for(nx=startlocal; nx<=stoplocal; nx++)*/
        for(nx=-info->nkx[0]/2; nx<info->nkx[0]/2+1; nx++) 
        {   
            svmul(nx,info->recipbox[XX],gridpx);
            for(ny=-info->nky[0]/2; ny<info->nky[0]/2+1; ny++)
            {
                svmul(ny,info->recipbox[YY],tmpvec);
                rvec_add(gridpx,tmpvec,gridpxy);
                for(nz=-info->nkz[0]/2; nz<info->nkz[0]/2+1; nz++)
                {
                    
                    if (  0 == nx && 0 == ny && 0 == nz)
                        continue;
                    
                    svmul(nz,info->recipbox[ZZ],tmpvec);
                    rvec_add(gridpxy,tmpvec,gridp);
                    tmp=norm2(gridp);
                    coeff=exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0] );
                    coeff/= tmp ;
                    e_rec3x+=coeff*eps_self(nx,info->nkx[0],info->recipbox[XX],info->pme_order[0],x[ci]);
                    e_rec3y+=coeff*eps_self(ny,info->nky[0],info->recipbox[YY],info->pme_order[0],x[ci]);
                    e_rec3z+=coeff*eps_self(nz,info->nkz[0],info->recipbox[ZZ],info->pme_order[0],x[ci]);

                }
            }
        }

        clear_rvec(tmpvec2);

        svmul(e_rec3x,info->recipbox[XX],tmpvec);
        rvec_inc(tmpvec2,tmpvec);
        svmul(e_rec3y,info->recipbox[YY],tmpvec);
        rvec_inc(tmpvec2,tmpvec);
        svmul(e_rec3z,info->recipbox[ZZ],tmpvec);
        rvec_inc(tmpvec2,tmpvec);

        e_rec3 += q[ci]*q[ci]*q[ci]*q[ci]*norm2(tmpvec2) / ( nrsamples * M_PI * info->volume * M_PI * info->volume); 
        if (MASTER(cr)){
            fprintf(stderr, "\rCalculating reciprocal error part 2 ... %3.0f%%",
                    100.0*(i+1)/stoplocal);

        }
       
    }

    if (MASTER(cr))
        fprintf(stderr, "\n");


#ifdef TAKETIME
    if (MASTER(cr))
    {
        t1= MPI_Wtime() - t0;
        fprintf(fp_out, "Recip. err. est. took   : %lf s\n", t1);
    }
#endif
   
#ifdef DEBUG
    if (PAR(cr))
    {
        fprintf(stderr, "Node %3d: nx=[%3d...%3d]  e_rec3=%e\n", 
                cr->nodeid, startlocal, stoplocal, e_rec3);
    }
#endif
   

/*
#ifdef GMX_MPI
    MPI_Barrier(MPI_COMM_WORLD);
#endif
  */ 

#ifdef TAKETIME
    if (MASTER(cr))
    {
        t2= MPI_Wtime() - t0;
        fprintf(fp_out, "barrier   : %lf s\n", t2-t1);
    }
#endif

    if (PAR(cr))
    {
        gmx_sum(1,&e_rec1,cr);
        gmx_sum(1,&e_rec2,cr);
        gmx_sum(1,&e_rec3,cr);
    }
    
#ifdef TAKETIME
    if (MASTER(cr))
        fprintf(fp_out, "final reduce : %lf s\n", MPI_Wtime() - t0-t2);
#endif
    /* e_rec1*=8.0 * q2_all / info->volume / info->volume / nr ;
       e_rec2*=  q2_all / M_PI / M_PI / info->volume / info->volume / nr ;
       e_rec3/= M_PI * M_PI * info->volume * info->volume * nr ; 
     */
    e_rec=sqrt(e_rec1+e_rec2+e_rec3);
    
    
    return ONE_4PI_EPS0 * e_rec;
}
Ejemplo n.º 15
0
static void insert_mols(int nmol_insrt, int ntry, int seed,
                        t_atoms *atoms, rvec **x, real **exclusionDistances,
                        t_atoms *atoms_insrt, rvec *x_insrt, real *exclusionDistances_insrt,
                        int ePBC, matrix box,
                        const char* posfn, const rvec deltaR, int enum_rot)
{
    t_pbc            pbc;
    rvec            *x_n;
    int              mol;
    int              trial;
    double         **rpos;

    const real       maxInsertRadius
        = *std::max_element(exclusionDistances_insrt,
                            exclusionDistances_insrt + atoms_insrt->nr);
    real             maxRadius = maxInsertRadius;
    if (atoms->nr > 0)
    {
        const real maxExistingRadius
            = *std::max_element(*exclusionDistances,
                                *exclusionDistances + atoms->nr);
        maxRadius = std::max(maxInsertRadius, maxExistingRadius);
    }

    // TODO: Make all of this exception-safe.
    gmx::AnalysisNeighborhood nb;
    nb.setCutoff(maxInsertRadius + maxRadius);

    gmx_rng_t        rng = gmx_rng_init(seed);
    set_pbc(&pbc, ePBC, box);

    snew(x_n, atoms_insrt->nr);

    /* With -ip, take nmol_insrt from file posfn */
    if (posfn != NULL)
    {
        int ncol;
        nmol_insrt = read_xvg(posfn, &rpos, &ncol);
        if (ncol != 3)
        {
            gmx_fatal(FARGS, "Expected 3 columns (x/y/z coordinates) in file %s\n", ncol, posfn);
        }
        fprintf(stderr, "Read %d positions from file %s\n\n", nmol_insrt, posfn);
    }

    {
        const int finalAtomCount    = atoms->nr + nmol_insrt * atoms_insrt->nr;
        const int finalResidueCount = atoms->nres + nmol_insrt * atoms_insrt->nres;
        srenew(atoms->resinfo,      finalResidueCount);
        srenew(atoms->atomname,     finalAtomCount);
        srenew(atoms->atom,         finalAtomCount);
        srenew(*x,                  finalAtomCount);
        srenew(*exclusionDistances, finalAtomCount);
    }

    trial = mol = 0;
    while ((mol < nmol_insrt) && (trial < ntry*nmol_insrt))
    {
        fprintf(stderr, "\rTry %d", trial++);
        rvec offset_x;
        if (posfn == NULL)
        {
            /* insert at random positions */
            offset_x[XX] = box[XX][XX] * gmx_rng_uniform_real(rng);
            offset_x[YY] = box[YY][YY] * gmx_rng_uniform_real(rng);
            offset_x[ZZ] = box[ZZ][ZZ] * gmx_rng_uniform_real(rng);
        }
        else
        {
            /* Insert at positions taken from option -ip file */
            offset_x[XX] = rpos[XX][mol] + deltaR[XX]*(2 * gmx_rng_uniform_real(rng)-1);
            offset_x[YY] = rpos[YY][mol] + deltaR[YY]*(2 * gmx_rng_uniform_real(rng)-1);
            offset_x[ZZ] = rpos[ZZ][mol] + deltaR[ZZ]*(2 * gmx_rng_uniform_real(rng)-1);
        }
        generate_trial_conf(atoms_insrt->nr, x_insrt, offset_x, enum_rot, rng,
                            x_n);
        gmx::AnalysisNeighborhoodPositions pos(*x, atoms->nr);
        gmx::AnalysisNeighborhoodSearch    search = nb.initSearch(&pbc, pos);
        if (is_insertion_allowed(&search, *exclusionDistances, atoms_insrt->nr,
                                 x_n, exclusionDistances_insrt))
        {
            const int firstIndex = atoms->nr;
            for (int i = 0; i < atoms_insrt->nr; ++i)
            {
                copy_rvec(x_n[i], (*x)[firstIndex + i]);
                (*exclusionDistances)[firstIndex + i] = exclusionDistances_insrt[i];
            }
            merge_atoms_noalloc(atoms, atoms_insrt);
            ++mol;
            fprintf(stderr, " success (now %d atoms)!\n", atoms->nr);
        }
    }
    gmx_rng_destroy(rng);
    srenew(atoms->resinfo,  atoms->nres);
    srenew(atoms->atomname, atoms->nr);
    srenew(atoms->atom,     atoms->nr);
    srenew(*x,              atoms->nr);
    srenew(*exclusionDistances, atoms->nr);

    fprintf(stderr, "\n");
    /* print number of molecules added */
    fprintf(stderr, "Added %d molecules (out of %d requested) of %s\n",
            mol, nmol_insrt, *atoms_insrt->resinfo[0].name);

    sfree(x_n);
}
Ejemplo n.º 16
0
static void insert_mols(int nmol_insrt, int ntry, int seed,
                        real defaultDistance, real scaleFactor,
                        t_atoms *atoms, rvec **x,
                        const t_atoms *atoms_insrt, const rvec *x_insrt,
                        int ePBC, matrix box,
                        const std::string &posfn, const rvec deltaR, int enum_rot)
{
    t_pbc            pbc;
    rvec            *x_n;

    fprintf(stderr, "Initialising inter-atomic distances...\n");
    gmx_atomprop_t   aps = gmx_atomprop_init();
    real            *exclusionDistances
        = makeExclusionDistances(atoms, aps, defaultDistance, scaleFactor);
    real            *exclusionDistances_insrt
        = makeExclusionDistances(atoms_insrt, aps, defaultDistance, scaleFactor);
    gmx_atomprop_destroy(aps);

    const real       maxInsertRadius
        = *std::max_element(exclusionDistances_insrt,
                            exclusionDistances_insrt + atoms_insrt->nr);
    real             maxRadius = maxInsertRadius;
    if (atoms->nr > 0)
    {
        const real maxExistingRadius
            = *std::max_element(exclusionDistances,
                                exclusionDistances + atoms->nr);
        maxRadius = std::max(maxInsertRadius, maxExistingRadius);
    }

    // TODO: Make all of this exception-safe.
    gmx::AnalysisNeighborhood nb;
    nb.setCutoff(maxInsertRadius + maxRadius);

    gmx_rng_t        rng = gmx_rng_init(seed);
    set_pbc(&pbc, ePBC, box);

    snew(x_n, atoms_insrt->nr);

    /* With -ip, take nmol_insrt from file posfn */
    double         **rpos = NULL;
    if (!posfn.empty())
    {
        int ncol;
        nmol_insrt = read_xvg(posfn.c_str(), &rpos, &ncol);
        if (ncol != 3)
        {
            gmx_fatal(FARGS, "Expected 3 columns (x/y/z coordinates) in file %s\n",
                      posfn.c_str());
        }
        fprintf(stderr, "Read %d positions from file %s\n\n",
                nmol_insrt, posfn.c_str());
    }

    {
        const int finalAtomCount    = atoms->nr + nmol_insrt * atoms_insrt->nr;
        const int finalResidueCount = atoms->nres + nmol_insrt * atoms_insrt->nres;
        srenew(atoms->resinfo,      finalResidueCount);
        srenew(atoms->atomname,     finalAtomCount);
        srenew(atoms->atom,         finalAtomCount);
        srenew(*x,                  finalAtomCount);
        srenew(exclusionDistances,  finalAtomCount);
    }

    int mol        = 0;
    int trial      = 0;
    int firstTrial = 0;
    int failed     = 0;
    while ((mol < nmol_insrt) && (trial < ntry*nmol_insrt))
    {
        rvec offset_x;
        if (posfn.empty())
        {
            // Insert at random positions.
            offset_x[XX] = box[XX][XX] * gmx_rng_uniform_real(rng);
            offset_x[YY] = box[YY][YY] * gmx_rng_uniform_real(rng);
            offset_x[ZZ] = box[ZZ][ZZ] * gmx_rng_uniform_real(rng);
        }
        else
        {
            // Skip a position if ntry trials were not successful.
            if (trial >= firstTrial + ntry)
            {
                fprintf(stderr, " skipped position (%.3f, %.3f, %.3f)\n",
                        rpos[XX][mol], rpos[YY][mol], rpos[ZZ][mol]);
                ++mol;
                ++failed;
            }
            // Insert at positions taken from option -ip file.
            offset_x[XX] = rpos[XX][mol] + deltaR[XX]*(2 * gmx_rng_uniform_real(rng)-1);
            offset_x[YY] = rpos[YY][mol] + deltaR[YY]*(2 * gmx_rng_uniform_real(rng)-1);
            offset_x[ZZ] = rpos[ZZ][mol] + deltaR[ZZ]*(2 * gmx_rng_uniform_real(rng)-1);
        }
        fprintf(stderr, "\rTry %d", ++trial);
        generate_trial_conf(atoms_insrt->nr, x_insrt, offset_x, enum_rot, rng,
                            x_n);
        gmx::AnalysisNeighborhoodPositions pos(*x, atoms->nr);
        gmx::AnalysisNeighborhoodSearch    search = nb.initSearch(&pbc, pos);
        if (is_insertion_allowed(&search, exclusionDistances, atoms_insrt->nr,
                                 x_n, exclusionDistances_insrt))
        {
            const int firstIndex = atoms->nr;
            for (int i = 0; i < atoms_insrt->nr; ++i)
            {
                copy_rvec(x_n[i], (*x)[firstIndex + i]);
                exclusionDistances[firstIndex + i] = exclusionDistances_insrt[i];
            }
            merge_atoms_noalloc(atoms, atoms_insrt);
            ++mol;
            firstTrial = trial;
            fprintf(stderr, " success (now %d atoms)!\n", atoms->nr);
        }
    }
    gmx_rng_destroy(rng);
    srenew(atoms->resinfo,  atoms->nres);
    srenew(atoms->atomname, atoms->nr);
    srenew(atoms->atom,     atoms->nr);
    srenew(*x,              atoms->nr);

    fprintf(stderr, "\n");
    /* print number of molecules added */
    fprintf(stderr, "Added %d molecules (out of %d requested)\n",
            mol - failed, nmol_insrt);

    sfree(x_n);
    sfree(exclusionDistances);
    sfree(exclusionDistances_insrt);
    if (rpos != NULL)
    {
        for (int i = 0; i < DIM; ++i)
        {
            sfree(rpos[i]);
        }
        sfree(rpos);
    }
}