Beispiel #1
0
static void init_proj_matrix(settleparam_t *p,
                             real invmO, real invmH, real dOH, real dHH)
{
    real   imOn, imHn;
    matrix mat;

    p->imO = invmO;
    p->imH = invmH;
    /* We normalize the inverse masses with imO for the matrix inversion.
     * so we can keep using masses of almost zero for frozen particles,
     * without running out of the float range in m_inv.
     */
    imOn = 1;
    imHn = p->imH/p->imO;

    /* Construct the constraint coupling matrix */
    mat[0][0] = imOn + imHn;
    mat[0][1] = imOn*(1 - 0.5*dHH*dHH/(dOH*dOH));
    mat[0][2] = imHn*0.5*dHH/dOH;
    mat[1][1] = mat[0][0];
    mat[1][2] = mat[0][2];
    mat[2][2] = imHn + imHn;
    mat[1][0] = mat[0][1];
    mat[2][0] = mat[0][2];
    mat[2][1] = mat[1][2];

    m_inv(mat, p->invmat);

    msmul(p->invmat, 1/p->imO, p->invmat);

    p->invdOH = 1/dOH;
    p->invdHH = 1/dHH;
}
Beispiel #2
0
/* the non-mass-weighted mean-squared displacement calcuation */
static real calc1_norm(t_corr *curr, int nx, atom_id index[], int nx0, rvec xc[],
                       rvec dcom, gmx_bool bTen, matrix mat)
{
    int  i, ix, m, m2;
    real g, r, r2;
    rvec rv;

    g = 0.0;
    clear_mat(mat);

    for (i = 0; (i < nx); i++)
    {
        ix = index[i];
        r2 = 0.0;
        switch (curr->type)
        {
            case NORMAL:
                for (m = 0; (m < DIM); m++)
                {
                    rv[m] = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m];
                    r2   += rv[m]*rv[m];
                    if (bTen)
                    {
                        for (m2 = 0; m2 <= m; m2++)
                        {
                            mat[m][m2] += rv[m]*rv[m2];
                        }
                    }
                }
                break;
            case X:
            case Y:
            case Z:
                r = xc[ix][curr->type-X] - curr->x0[nx0][ix][curr->type-X] -
                    dcom[curr->type-X];
                r2 += r*r;
                break;
            case LATERAL:
                for (m = 0; (m < DIM); m++)
                {
                    if (m != curr->axis)
                    {
                        r   = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m];
                        r2 += r*r;
                    }
                }
                break;
            default:
                gmx_fatal(FARGS, "Error: did not expect option value %d", curr->type);
        }
        g += r2;
    }
    g /= nx;
    msmul(mat, 1.0/nx, mat);

    return g;
}
static void boxv_trotter(t_inputrec *ir, real *veta, real dt, tensor box, 
                         gmx_ekindata_t *ekind, tensor vir, real pcorr, real ecorr, t_extmass *MassQ)
{

    real  pscal;
    double alpha;
    int   i,j,d,n,nwall;
    real  T,GW,vol;
    tensor Winvm,ekinmod,localpres;
    
    /* The heat bath is coupled to a separate barostat, the last temperature group.  In the 
       2006 Tuckerman et al paper., the order is iL_{T_baro} iL {T_part}
    */
    
    if (ir->epct==epctSEMIISOTROPIC) 
    {
        nwall = 2;
    } 
    else 
    {
        nwall = 3;
    }

    /* eta is in pure units.  veta is in units of ps^-1. GW is in 
       units of ps^-2.  However, eta has a reference of 1 nm^3, so care must be 
       taken to use only RATIOS of eta in updating the volume. */
    
    /* we take the partial pressure tensors, modify the 
       kinetic energy tensor, and recovert to pressure */
    
    if (ir->opts.nrdf[0]==0) 
    { 
        gmx_fatal(FARGS,"Barostat is coupled to a T-group with no degrees of freedom\n");    
    } 
    /* alpha factor for phase space volume, then multiply by the ekin scaling factor.  */
    alpha = 1.0 + DIM/((double)ir->opts.nrdf[0]);
    alpha *= ekind->tcstat[0].ekinscalef_nhc;
    msmul(ekind->ekin,alpha,ekinmod);  
    
    /* for now, we use Elr = 0, because if you want to get it right, you
       really should be using PME. Maybe print a warning? */
    
    pscal   = calc_pres(ir->ePBC,nwall,box,ekinmod,vir,localpres,0.0) + pcorr;
    
    vol = det(box);
    GW = (vol*(MassQ->Winv/PRESFAC))*(DIM*pscal - trace(ir->ref_p));   /* W is in ps^2 * bar * nm^3 */
    
    *veta += 0.5*dt*GW;   
}
/* the normal, mass-weighted mean-squared displacement calcuation */
static real calc1_mw(t_corr *curr,int nx,atom_id index[],int nx0,rvec xc[],
		     rvec dcom,gmx_bool bTen,matrix mat,const output_env_t oenv)
{
  int  i;
  real g,tm;

  g=tm=0.0;
  clear_mat(mat);
  for(i=0; (i<nx); i++) 
    g += calc_one_mw(curr,index[i],nx0,xc,&tm,dcom,bTen,mat);
  
  g/=tm;
  if (bTen)
    msmul(mat,1/tm,mat);

  return g;
}
static real calc1_mol(t_corr *curr,int nx,atom_id index[],int nx0,rvec xc[],
		      rvec dcom,gmx_bool bTen,matrix mat, const output_env_t oenv)
{
  int  i;
  real g,tm,gtot,tt;

  tt = curr->time[in_data(curr,nx0)];
  gtot = 0;
  tm = 0;
  clear_mat(mat);
  for(i=0; (i<nx); i++) {
    g = calc_one_mw(curr,i,nx0,xc,&tm,dcom,bTen,mat);
    /* We don't need to normalize as the mass was set to 1 */
    gtot += g;
    if (tt >= curr->beginfit && (curr->endfit < 0 || tt <= curr->endfit))
      gmx_stats_add_point(curr->lsq[nx0][i],tt,g,0,0);
  }
  msmul(mat,1.0/nx,mat);

  return gtot/nx;
}
Beispiel #6
0
/* the normal, mass-weighted mean-squared displacement calcuation */
static real calc1_mw(t_corr *curr, int nx, int index[], int nx0, rvec xc[],
                     rvec dcom, gmx_bool bTen, matrix mat)
{
    int  i;
    real g, tm;

    g = tm = 0.0;
    clear_mat(mat);
    for (i = 0; (i < nx); i++)
    {
        g += calc_one_mw(curr, index[i], nx0, xc, &tm, dcom, bTen, mat);
    }

    g /= tm;
    if (bTen)
    {
        msmul(mat, 1/tm, mat);
    }

    return g;
}
Beispiel #7
0
real sum_ekin(t_grpopts *opts, gmx_ekindata_t *ekind, real *dekindlambda,
              gmx_bool bEkinAveVel, gmx_bool bSaveEkinOld, gmx_bool bScaleEkin)
{
    int           i, j, m, ngtc;
    real          T, ek;
    t_grp_tcstat *tcstat;
    real          nrdf, nd, *ndf;

    ngtc = opts->ngtc;
    ndf  = opts->nrdf;

    T    = 0;
    nrdf = 0;

    clear_mat(ekind->ekin);

    for (i = 0; (i < ngtc); i++)
    {

        nd     = ndf[i];
        tcstat = &ekind->tcstat[i];
        /* Sometimes a group does not have degrees of freedom, e.g.
         * when it consists of shells and virtual sites, then we just
         * set the temperatue to 0 and also neglect the kinetic
         * energy, which should be  zero anyway.
         */

        if (nd > 0)
        {
            if (bEkinAveVel)
            {
                if (!bScaleEkin)
                {
                    /* in this case, kinetic energy is from the current velocities already */
                    msmul(tcstat->ekinf, tcstat->ekinscalef_nhc, tcstat->ekinf);
                }
            }
            else

            {
                /* Calculate the full step Ekin as the average of the half steps */
                for (j = 0; (j < DIM); j++)
                {
                    for (m = 0; (m < DIM); m++)
                    {
                        tcstat->ekinf[j][m] =
                            0.5*(tcstat->ekinh[j][m]*tcstat->ekinscaleh_nhc + tcstat->ekinh_old[j][m]);
                    }
                }
            }
            m_add(tcstat->ekinf, ekind->ekin, ekind->ekin);

            tcstat->Th = calc_temp(trace(tcstat->ekinh), nd);
            tcstat->T  = calc_temp(trace(tcstat->ekinf), nd);

            /* after the scaling factors have been multiplied in, we can remove them */
            if (bEkinAveVel)
            {
                tcstat->ekinscalef_nhc = 1.0;
            }
            else
            {
                tcstat->ekinscaleh_nhc = 1.0;
            }
        }
        else
        {
            tcstat->T  = 0;
            tcstat->Th = 0;
        }
        T    += nd*tcstat->T;
        nrdf += nd;
    }
    if (nrdf > 0)
    {
        T /= nrdf;
    }
    if (dekindlambda)
    {
        *dekindlambda = 0.5*(ekind->dekindl + ekind->dekindl_old);
    }
    return T;
}
void settle_proj(FILE *fp,int nsettle, t_iatom iatoms[],rvec x[],
		 real dOH,real dHH,real invmO,real invmH,
		 rvec *der,rvec *derp,
		 bool bCalcVir,tensor rmdder)
{
  /* Settle for projection out constraint components
   * of derivatives of the coordinates.
   * Berk Hess 2008-1-10
   */

  /* Initialized data */
  static bool bFirst=TRUE;
  static real imO,imH,invdOH,invdHH;
  static matrix invmat;

  real imOn,imHn;
  matrix mat;
  int i,m,m2,ow1,hw2,hw3;
  rvec roh2,roh3,rhh,dc,fc;

  if (bFirst) {
    if (fp)
      fprintf(fp,"Going to use settle for derivatives (%d waters)\n",nsettle);

    imO = invmO;
    imH = invmH;
    /* We normalize the inverse masses with imO for the matrix inversion.
     * so we can keep using masses of almost zero for frozen particles,
     * without running out of the float range in m_inv.
     */
    imOn = 1;
    imHn = imH/imO;

    /* Construct the constraint coupling matrix */
    mat[0][0] = imOn + imHn;
    mat[0][1] = imOn*(1 - 0.5*dHH*dHH/(dOH*dOH));
    mat[0][2] = imHn*0.5*dHH/dOH;
    mat[1][1] = mat[0][0];
    mat[1][2] = mat[0][2];
    mat[2][2] = imHn + imHn;
    mat[1][0] = mat[0][1];
    mat[2][0] = mat[0][2];
    mat[2][1] = mat[1][2];

    m_inv(mat,invmat);

    msmul(invmat,1/imO,invmat);

    invdOH = 1/dOH;
    invdHH = 1/dHH;

    bFirst = FALSE;
  }

#ifdef PRAGMAS
#pragma ivdep
#endif
  for (i=0; i<nsettle; i++) {
    ow1 = iatoms[i*2+1];
    hw2 = ow1 + 1;
    hw3 = ow1 + 2;
    
    for(m=0; m<DIM; m++)
      roh2[m] = (x[ow1][m] - x[hw2][m])*invdOH;
    for(m=0; m<DIM; m++)
      roh3[m] = (x[ow1][m] - x[hw3][m])*invdOH;
    for(m=0; m<DIM; m++)
      rhh [m] = (x[hw2][m] - x[hw3][m])*invdHH;
    /* 18 flops */

    /* Determine the projections of der on the bonds */
    clear_rvec(dc);
    for(m=0; m<DIM; m++)
      dc[0] += (der[ow1][m] - der[hw2][m])*roh2[m];
    for(m=0; m<DIM; m++)
      dc[1] += (der[ow1][m] - der[hw3][m])*roh3[m];
    for(m=0; m<DIM; m++)
      dc[2] += (der[hw2][m] - der[hw3][m])*rhh [m];
    /* 27 flops */

    /* Determine the correction for the three bonds */
    mvmul(invmat,dc,fc);
    /* 15 flops */

    /* Subtract the corrections from derp */
    for(m=0; m<DIM; m++) {
      derp[ow1][m] -= imO*( fc[0]*roh2[m] + fc[1]*roh3[m]);
      derp[hw2][m] -= imH*(-fc[0]*roh2[m] + fc[2]*rhh [m]);
      derp[hw3][m] -= imH*(-fc[1]*roh3[m] - fc[2]*rhh [m]);
    }
    /* 45 flops */

    if (bCalcVir) {
      /* Determining r x m der is easy,
       * since fc contains the mass weighted corrections for der.
       */
      for(m=0; m<DIM; m++) {
	for(m2=0; m2<DIM; m2++) {
	  rmdder[m][m2] +=
	    dOH*roh2[m]*roh2[m2]*fc[0] +
	    dOH*roh3[m]*roh3[m2]*fc[1] +
	    dHH*rhh [m]*rhh [m2]*fc[2];
	}
      }
    }
  }
}
Beispiel #9
0
int gmx_vanhove(int argc,char *argv[])
{
  const char *desc[] = {
    "g_vanhove computes the Van Hove correlation function.",
    "The Van Hove G(r,t) is the probability that a particle that is at r0",
    "at time zero can be found at position r0+r at time t.",
    "g_vanhove determines G not for a vector r, but for the length of r.",
    "Thus it gives the probability that a particle moves a distance of r",
    "in time t.",
    "Jumps across the periodic boundaries are removed.",
    "Corrections are made for scaling due to isotropic",
    "or anisotropic pressure coupling.",
    "[PAR]",
    "With option [TT]-om[tt] the whole matrix can be written as a function",
    "of t and r or as a function of sqrt(t) and r (option [TT]-sqrt[tt]).",
    "[PAR]",
    "With option [TT]-or[tt] the Van Hove function is plotted for one",
    "or more values of t. Option [TT]-nr[tt] sets the number of times,",
    "option [TT]-fr[tt] the number spacing between the times.",
    "The binwidth is set with option [TT]-rbin[tt]. The number of bins",
    "is determined automatically.",
    "[PAR]",
    "With option [TT]-ot[tt] the integral up to a certain distance",
    "(option [TT]-rt[tt]) is plotted as a function of time.",
    "[PAR]",
    "For all frames that are read the coordinates of the selected particles",
    "are stored in memory. Therefore the program may use a lot of memory.",
    "For options [TT]-om[tt] and [TT]-ot[tt] the program may be slow.",
    "This is because the calculation scales as the number of frames times",
    "[TT]-fm[tt] or [TT]-ft[tt].",
    "Note that with the [TT]-dt[tt] option the memory usage and calculation",
    "time can be reduced."
  };
  static int fmmax=0,ftmax=0,nlev=81,nr=1,fshift=0;
  static real sbin=0,rmax=2,rbin=0.01,mmax=0,rint=0;
  t_pargs pa[] = {
    { "-sqrt",    FALSE, etREAL,{&sbin},
      "Use sqrt(t) on the matrix axis which binspacing # in sqrt(ps)" },
    { "-fm",      FALSE, etINT, {&fmmax},
      "Number of frames in the matrix, 0 is plot all" },
    { "-rmax",    FALSE, etREAL, {&rmax},
      "Maximum r in the matrix (nm)" },
    { "-rbin",    FALSE, etREAL, {&rbin},
      "Binwidth in the matrix and for -or (nm)" },
    { "-mmax",    FALSE, etREAL, {&mmax},
      "Maximum density in the matrix, 0 is calculate (1/nm)" },
    { "-nlevels" ,FALSE, etINT,  {&nlev}, 
      "Number of levels in the matrix" },
    { "-nr",      FALSE, etINT, {&nr},
      "Number of curves for the -or output" },
    { "-fr",      FALSE, etINT, {&fshift},
      "Frame spacing for the -or output" },
    { "-rt",      FALSE, etREAL, {&rint},
      "Integration limit for the -ot output (nm)" },
    { "-ft",      FALSE, etINT, {&ftmax},
      "Number of frames in the -ot output, 0 is plot all" }
  };
#define NPA asize(pa)

  t_filenm fnm[] = { 
    { efTRX, NULL, NULL,  ffREAD },
    { efTPS, NULL, NULL,  ffREAD }, 
    { efNDX, NULL, NULL,  ffOPTRD },
    { efXPM, "-om", "vanhove", ffOPTWR },
    { efXVG, "-or", "vanhove_r", ffOPTWR },
    { efXVG, "-ot", "vanhove_t", ffOPTWR }
  };
#define NFILE asize(fnm)

  output_env_t oenv;
  const char *matfile,*otfile,*orfile;
  char     title[256];
  t_topology top;
  int      ePBC;
  matrix   boxtop,box,*sbox,avbox,corr;
  rvec     *xtop,*x,**sx;
  int      isize,nalloc,nallocn,natom;
  t_trxstatus *status;
  atom_id  *index;
  char     *grpname;
  int      nfr,f,ff,i,m,mat_nx=0,nbin=0,bin,mbin,fbin;
  real     *time,t,invbin=0,rmax2=0,rint2=0,d2;
  real     invsbin=0,matmax,normfac,dt,*tickx,*ticky;
  char     buf[STRLEN],**legend;
  real     **mat=NULL;
  int      *pt=NULL,**pr=NULL,*mcount=NULL,*tcount=NULL,*rcount=NULL;
  FILE     *fp;
  t_rgb    rlo={1,1,1}, rhi={0,0,0};

  CopyRight(stderr,argv[0]);

  parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv);
  
  matfile = opt2fn_null("-om",NFILE,fnm);
  if (opt2parg_bSet("-fr",NPA,pa))
    orfile  = opt2fn("-or",NFILE,fnm);
  else
    orfile  = opt2fn_null("-or",NFILE,fnm);
  if (opt2parg_bSet("-rt",NPA,pa))
    otfile  = opt2fn("-ot",NFILE,fnm);
  else
    otfile  = opt2fn_null("-ot",NFILE,fnm);
  
  if (!matfile && !otfile && !orfile) {
    fprintf(stderr,
	    "For output set one (or more) of the output file options\n");
    exit(0);
  }
  
  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xtop,NULL,boxtop,
		FALSE); 
  get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&isize,&index,&grpname);
  
  nalloc = 0;
  time = NULL;
  sbox = NULL;
  sx   = NULL;
  clear_mat(avbox);

  natom=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
  nfr = 0;
  do {
    if (nfr >= nalloc) {
      nalloc += 100;
      srenew(time,nalloc);
      srenew(sbox,nalloc);
      srenew(sx,nalloc);
    }
    
    time[nfr] = t;
    copy_mat(box,sbox[nfr]);
    /* This assumes that the off-diagonal box elements
     * are not affected by jumps across the periodic boundaries.
     */
    m_add(avbox,box,avbox);
    snew(sx[nfr],isize);
    for(i=0; i<isize; i++)
     copy_rvec(x[index[i]],sx[nfr][i]);
    
    nfr++;
  } while (read_next_x(oenv,status,&t,natom,x,box));

  /* clean up */
  sfree(x);
  close_trj(status);
  
  fprintf(stderr,"Read %d frames\n",nfr);

  dt = (time[nfr-1] - time[0])/(nfr - 1);
  /* Some ugly rounding to get nice nice times in the output */
  dt = (int)(10000.0*dt + 0.5)/10000.0;

  invbin = 1.0/rbin;

  if (matfile) {
    if (fmmax <= 0 || fmmax >= nfr)
      fmmax = nfr - 1;
    snew(mcount,fmmax);
    nbin = (int)(rmax*invbin + 0.5);
    if (sbin == 0) {
      mat_nx = fmmax + 1;
    } else {
      invsbin = 1.0/sbin;
      mat_nx = sqrt(fmmax*dt)*invsbin + 1;
    }
    snew(mat,mat_nx);
    for(f=0; f<mat_nx; f++)
      snew(mat[f],nbin);
    rmax2 = sqr(nbin*rbin);
    /* Initialize time zero */
    mat[0][0] = nfr*isize;
    mcount[0] += nfr;
  } else {
    fmmax = 0;
  }
  
  if (orfile) {
    snew(pr,nr);
    nalloc = 0;
    snew(rcount,nr);
  }
  
  if (otfile) {
    if (ftmax <= 0)
      ftmax = nfr - 1;
    snew(tcount,ftmax);
    snew(pt,nfr);
    rint2 = rint*rint;
    /* Initialize time zero */
    pt[0] = nfr*isize;
    tcount[0] += nfr;
  } else {
    ftmax = 0;
  }

  msmul(avbox,1.0/nfr,avbox);
  for(f=0; f<nfr; f++) {
    if (f % 100 == 0)
      fprintf(stderr,"\rProcessing frame %d",f);
    /* Scale all the configuration to the average box */
    m_inv_ur0(sbox[f],corr);
    mmul_ur0(avbox,corr,corr);
    for(i=0; i<isize; i++) {
      mvmul_ur0(corr,sx[f][i],sx[f][i]);
      if (f > 0) {
	/* Correct for periodic jumps */
	for(m=DIM-1; m>=0; m--) {
	  while(sx[f][i][m] - sx[f-1][i][m] > 0.5*avbox[m][m])
	    rvec_dec(sx[f][i],avbox[m]);
	  while(sx[f][i][m] - sx[f-1][i][m] <= -0.5*avbox[m][m])
	    rvec_inc(sx[f][i],avbox[m]);
	}
      }
    }
    for(ff=0; ff<f; ff++) {
      fbin = f - ff;
      if (fbin <= fmmax || fbin <= ftmax) {
	if (sbin == 0)
	  mbin = fbin;
	else
	  mbin = (int)(sqrt(fbin*dt)*invsbin + 0.5);
	for(i=0; i<isize; i++) {
	  d2 = distance2(sx[f][i],sx[ff][i]);
	  if (mbin < mat_nx && d2 < rmax2) {
	    bin = (int)(sqrt(d2)*invbin + 0.5);
	    if (bin < nbin) {
	      mat[mbin][bin] += 1;
	    }
	  }
	  if (fbin <= ftmax && d2 <= rint2)
	    pt[fbin]++;
	}
	if (matfile)
	  mcount[mbin]++;
	if (otfile)
	  tcount[fbin]++;
      }
    }
    if (orfile) {
      for(fbin=0; fbin<nr; fbin++) {
	ff = f - (fbin + 1)*fshift;
	if (ff >= 0) {
	  for(i=0; i<isize; i++) {
	    d2 = distance2(sx[f][i],sx[ff][i]);
	    bin = (int)(sqrt(d2)*invbin);
	    if (bin >= nalloc) {
	      nallocn = 10*(bin/10) + 11;
	      for(m=0; m<nr; m++) {
		srenew(pr[m],nallocn);
		for(i=nalloc; i<nallocn; i++)
		  pr[m][i] = 0;
	      }
	      nalloc = nallocn;
	    }
	    pr[fbin][bin]++;
	  }
	  rcount[fbin]++;
	}
      }
    }
  }
  fprintf(stderr,"\n");
  
  if (matfile) {
    matmax = 0;
    for(f=0; f<mat_nx; f++) {
      normfac = 1.0/(mcount[f]*isize*rbin);
      for(i=0; i<nbin; i++) {
	mat[f][i] *= normfac;
	if (mat[f][i] > matmax && (f!=0 || i!=0))
	  matmax = mat[f][i];
      }
    }
    fprintf(stdout,"Value at (0,0): %.3f, maximum of the rest %.3f\n",
	    mat[0][0],matmax);
    if (mmax > 0)
      matmax = mmax;
    snew(tickx,mat_nx);
    for(f=0; f<mat_nx; f++) {
      if (sbin == 0)
	tickx[f] = f*dt;
      else
	tickx[f] = f*sbin;
    }
    snew(ticky,nbin+1);
    for(i=0; i<=nbin; i++)
      ticky[i] = i*rbin;
    fp = ffopen(matfile,"w");
    write_xpm(fp,MAT_SPATIAL_Y,"Van Hove function","G (1/nm)",
	      sbin==0 ? "time (ps)" : "sqrt(time) (ps^1/2)","r (nm)",
	      mat_nx,nbin,tickx,ticky,mat,0,matmax,rlo,rhi,&nlev);     
    ffclose(fp);
  }
  
  if (orfile) {
    fp = xvgropen(orfile,"Van Hove function","r (nm)","G (nm\\S-1\\N)",oenv);
    fprintf(fp,"@ subtitle \"for particles in group %s\"\n",grpname);
    snew(legend,nr);
    for(fbin=0; fbin<nr; fbin++) {
      sprintf(buf,"%g ps",(fbin + 1)*fshift*dt);
      legend[fbin] = strdup(buf);
    }
    xvgr_legend(fp,nr,(const char**)legend,oenv);
    for(i=0; i<nalloc; i++) {
      fprintf(fp,"%g",i*rbin);
      for(fbin=0; fbin<nr; fbin++)
	fprintf(fp," %g",
		(real)pr[fbin][i]/(rcount[fbin]*isize*rbin*(i==0 ? 0.5 : 1)));
      fprintf(fp,"\n");
    }
    ffclose(fp);
  }
  
  if (otfile) {
    sprintf(buf,"Probability of moving less than %g nm",rint);
    fp = xvgropen(otfile,buf,"t (ps)","",oenv);
    fprintf(fp,"@ subtitle \"for particles in group %s\"\n",grpname);
    for(f=0; f<=ftmax; f++)
      fprintf(fp,"%g %g\n",f*dt,(real)pt[f]/(tcount[f]*isize));
    ffclose(fp);
  }

  do_view(oenv, matfile,NULL);
  do_view(oenv, orfile,NULL);
  do_view(oenv, otfile,NULL);

  thanx(stderr);
  
  return 0;
}
Beispiel #10
0
void do_corr(const char *trx_file, const char *ndx_file, const char *msd_file,
             const char *mol_file, const char *pdb_file, real t_pdb,
             int nrgrp, t_topology *top, int ePBC,
             gmx_bool bTen, gmx_bool bMW, gmx_bool bRmCOMM,
             int type, real dim_factor, int axis,
             real dt, real beginfit, real endfit, const output_env_t oenv)
{
    t_corr        *msd;
    int           *gnx;   /* the selected groups' sizes */
    atom_id      **index; /* selected groups' indices */
    char         **grpname;
    int            i, i0, i1, j, N, nat_trx;
    real          *DD, *SigmaD, a, a2, b, r, chi2;
    rvec          *x;
    matrix         box;
    int           *gnx_com     = NULL; /* the COM removal group size  */
    atom_id      **index_com   = NULL; /* the COM removal group atom indices */
    char         **grpname_com = NULL; /* the COM removal group name */

    snew(gnx, nrgrp);
    snew(index, nrgrp);
    snew(grpname, nrgrp);

    fprintf(stderr, "\nSelect a group to calculate mean squared displacement for:\n");
    get_index(&top->atoms, ndx_file, nrgrp, gnx, index, grpname);

    if (bRmCOMM)
    {
        snew(gnx_com, 1);
        snew(index_com, 1);
        snew(grpname_com, 1);

        fprintf(stderr, "\nNow select a group for center of mass removal:\n");
        get_index(&top->atoms, ndx_file, 1, gnx_com, index_com, grpname_com);
    }

    if (mol_file)
    {
        index_atom2mol(&gnx[0], index[0], &top->mols);
    }

    msd = init_corr(nrgrp, type, axis, dim_factor,
                    mol_file == NULL ? 0 : gnx[0], bTen, bMW, dt, top,
                    beginfit, endfit);

    nat_trx =
        corr_loop(msd, trx_file, top, ePBC, mol_file ? gnx[0] : 0, gnx, index,
                  (mol_file != NULL) ? calc1_mol : (bMW ? calc1_mw : calc1_norm),
                  bTen, gnx_com, index_com, dt, t_pdb,
                  pdb_file ? &x : NULL, box, oenv);

    /* Correct for the number of points */
    for (j = 0; (j < msd->ngrp); j++)
    {
        for (i = 0; (i < msd->nframes); i++)
        {
            msd->data[j][i] /= msd->ndata[j][i];
            if (bTen)
            {
                msmul(msd->datam[j][i], 1.0/msd->ndata[j][i], msd->datam[j][i]);
            }
        }
    }

    if (mol_file)
    {
        if (pdb_file && x == NULL)
        {
            fprintf(stderr, "\nNo frame found need time tpdb = %g ps\n"
                    "Can not write %s\n\n", t_pdb, pdb_file);
        }
        i             = top->atoms.nr;
        top->atoms.nr = nat_trx;
        printmol(msd, mol_file, pdb_file, index[0], top, x, ePBC, box, oenv);
        top->atoms.nr = i;
    }

    DD     = NULL;
    SigmaD = NULL;

    if (beginfit == -1)
    {
        i0       = static_cast<int>(0.1*(msd->nframes - 1) + 0.5);
        beginfit = msd->time[i0];
    }
    else
    {
        for (i0 = 0; i0 < msd->nframes && msd->time[i0] < beginfit; i0++)
        {
            ;
        }
    }

    if (endfit == -1)
    {
        i1     = static_cast<int>(0.9*(msd->nframes - 1) + 0.5) + 1;
        endfit = msd->time[i1-1];
    }
    else
    {
        for (i1 = i0; i1 < msd->nframes && msd->time[i1] <= endfit; i1++)
        {
            ;
        }
    }
    fprintf(stdout, "Fitting from %g to %g %s\n\n", beginfit, endfit,
            output_env_get_time_unit(oenv));

    N = i1-i0;
    if (N <= 2)
    {
        fprintf(stdout, "Not enough points for fitting (%d).\n"
                "Can not determine the diffusion constant.\n", N);
    }
    else
    {
        snew(DD, msd->ngrp);
        snew(SigmaD, msd->ngrp);
        for (j = 0; j < msd->ngrp; j++)
        {
            if (N >= 4)
            {
                lsq_y_ax_b(N/2, &(msd->time[i0]), &(msd->data[j][i0]), &a, &b, &r, &chi2);
                lsq_y_ax_b(N/2, &(msd->time[i0+N/2]), &(msd->data[j][i0+N/2]), &a2, &b, &r, &chi2);
                SigmaD[j] = std::abs(a-a2);
            }
            else
            {
                SigmaD[j] = 0;
            }
            lsq_y_ax_b(N, &(msd->time[i0]), &(msd->data[j][i0]), &(DD[j]), &b, &r, &chi2);
            DD[j]     *= FACTOR/msd->dim_factor;
            SigmaD[j] *= FACTOR/msd->dim_factor;
            if (DD[j] > 0.01 && DD[j] < 1e4)
            {
                fprintf(stdout, "D[%10s] %.4f (+/- %.4f) 1e-5 cm^2/s\n",
                        grpname[j], DD[j], SigmaD[j]);
            }
            else
            {
                fprintf(stdout, "D[%10s] %.4g (+/- %.4g) 1e-5 cm^2/s\n",
                        grpname[j], DD[j], SigmaD[j]);
            }
        }
    }
    /* Print mean square displacement */
    corr_print(msd, bTen, msd_file,
               "Mean Square Displacement",
               "MSD (nm\\S2\\N)",
               msd->time[msd->nframes-1], beginfit, endfit, DD, SigmaD, grpname, oenv);
}
Beispiel #11
0
void settle_proj(FILE *fp,
                 gmx_settledata_t settled,int econq,
                 int nsettle, t_iatom iatoms[],rvec x[],
                 rvec *der,rvec *derp,
                 gmx_bool bCalcVir,tensor rmdder,t_vetavars *vetavar)
{
    /* Settle for projection out constraint components
     * of derivatives of the coordinates.
     * Berk Hess 2008-1-10
     */
    
    settleparam_t *p;
    real   imO,imH,dOH,dHH,invdOH,invdHH;
    matrix invmat;
    int    i,m,m2,ow1,hw2,hw3;
    rvec   roh2,roh3,rhh,dc,fc,fcv;
    rvec   derm[3],derpm[3];
    real   invvscale,vscale_nhc,veta;
    real   kfacOH,kfacHH;

    if (econq == econqForce)
    {
        p = &settled->mass1;
    }
    else
    {
        p = &settled->massw;
    }
    imO    = p->imO;
    imH    = p->imH;
    copy_mat(p->invmat,invmat);
    dOH    = p->dOH;
    dHH    = p->dHH;
    invdOH = p->invdOH;
    invdHH = p->invdHH;
    
    veta = vetavar->veta;     
    vscale_nhc = vetavar->vscale_nhc[0]; /* assume the first temperature control group. */

#ifdef PRAGMAS
#pragma ivdep
#endif
    
    for (i=0; i<nsettle; i++)
    {
        ow1 = iatoms[i*2+1];
        hw2 = ow1 + 1;
        hw3 = ow1 + 2;


        for(m=0; m<DIM; m++)
        {
            /* in the velocity case, these are the velocities, so we 
               need to modify with the pressure control velocities! */
            
            derm[0][m]  = vscale_nhc*der[ow1][m] + veta*x[ow1][m];
            derm[1][m]  = vscale_nhc*der[hw2][m] + veta*x[hw2][m];
            derm[2][m]  = vscale_nhc*der[hw3][m] + veta*x[hw3][m];
            
        }
        /* 27 flops */
        
        for(m=0; m<DIM; m++)
        {
            roh2[m] = (x[ow1][m] - x[hw2][m])*invdOH;
            roh3[m] = (x[ow1][m] - x[hw3][m])*invdOH;
            rhh [m] = (x[hw2][m] - x[hw3][m])*invdHH;
        }
        /* 18 flops */
        
        /* Determine the projections of der(modified) on the bonds */
        clear_rvec(dc);
        for(m=0; m<DIM; m++)
        {
            dc[0] += (derm[0][m] - derm[1][m])*roh2[m];
            dc[1] += (derm[0][m] - derm[2][m])*roh3[m];
            dc[2] += (derm[1][m] - derm[2][m])*rhh [m];
        }
        /* 27 flops */
        
        /* Determine the correction for the three bonds */
        mvmul(invmat,dc,fc);
        /* 15 flops */
        
        /* divide velocity by vscale_nhc for determining constrained velocities, since they 
           have not yet been multiplied */
        svmul(1.0/vscale_nhc,fc,fcv);
        /* 7? flops */
        
        /* Subtract the corrections from derp */
        for(m=0; m<DIM; m++)
        {
            derp[ow1][m] -= imO*( fcv[0]*roh2[m] + fcv[1]*roh3[m]);
            derp[hw2][m] -= imH*(-fcv[0]*roh2[m] + fcv[2]*rhh [m]);
            derp[hw3][m] -= imH*(-fcv[1]*roh3[m] - fcv[2]*rhh [m]);
        }
        
        /* 45 flops */

        if (bCalcVir)
        {
            /* Determining r \dot m der is easy,
             * since fc contains the mass weighted corrections for der.
             */
            
            for(m=0; m<DIM; m++)
            {
                for(m2=0; m2<DIM; m2++)
                {
                    rmdder[m][m2] +=
                        dOH*roh2[m]*roh2[m2]*fcv[0] +
                        dOH*roh3[m]*roh3[m2]*fcv[1] +
                        dHH*rhh [m]*rhh [m2]*fcv[2]; 
                }
            }
        }
    }
    /* conrect rmdder, which will be used to calcualate the virial; we need to use 
       the unscaled multipliers in the virial */
    msmul(rmdder,1.0/vetavar->vscale,rmdder);
}