Пример #1
0
void do_four(const char *fn, const char *cn, int nx, real x[], real dy[],
             real eps0, real epsRF, const output_env_t oenv)
{
    FILE      *fp, *cp;
    t_complex *tmp, gw, hw, kw;
    int        i, nnx, nxsav;
    real       fac, nu, dt, *ptr, maxeps, numax;

    nxsav = nx;
    /*while ((dy[nx-1] == 0.0) && (nx > 0))
       nx--;*/
    if (nx == 0)
    {
        gmx_fatal(FARGS, "Empty dataset in %s, line %d!", __FILE__, __LINE__);
    }

    nnx = 1;
    while (nnx < 2*nx)
    {
        nnx *= 2;
    }
    snew(tmp, 2*nnx);
    printf("Doing FFT of %d points\n", nnx);
    for (i = 0; (i < nx); i++)
    {
        tmp[i].re = dy[i];
    }
    ptr = &tmp[0].re;
    four1(ptr-1, nnx, -1);

    dt = x[1]-x[0];
    if (epsRF == 0)
    {
        fac = (eps0-1)/tmp[0].re;
    }
    else
    {
        fac = ((eps0-1)/(2*epsRF+eps0))/tmp[0].re;
    }
    fp     = xvgropen(fn, "Epsilon(\\8w\\4)", "Freq. (GHz)", "eps", oenv);
    cp     = xvgropen(cn, "Cole-Cole plot", "Eps'", "Eps''", oenv);
    maxeps = 0;
    numax  = 0;
    for (i = 0; (i < nxsav); i++)
    {
        if (epsRF == 0)
        {
            kw.re = 1+fac*tmp[i].re;
            kw.im = 1+fac*tmp[i].im;
        }
        else
        {
            gw     = rcmul(fac, tmp[i]);
            hw     = rcmul(2*epsRF, gw);
            hw.re += 1.0;
            gw.re  = 1.0 - gw.re;
            gw.im  = -gw.im;
            kw     = cdiv(hw, gw);
        }
        kw.im *= -1;

        nu     = (i+1)*1000.0/(nnx*dt);
        if (kw.im > maxeps)
        {
            maxeps = kw.im;
            numax  = nu;
        }

        fprintf(fp, "%10.5e  %10.5e  %10.5e\n", nu, kw.re, kw.im);
        fprintf(cp, "%10.5e  %10.5e\n", kw.re, kw.im);
    }
    printf("MAXEPS = %10.5e at frequency %10.5e GHz (tauD = %8.1f ps)\n",
           maxeps, numax, 1000/(2*M_PI*numax));
    ffclose(fp);
    ffclose(cp);
    sfree(tmp);
}
Пример #2
0
real do_ewald(t_inputrec *ir,
              rvec x[],        rvec f[],
              real chargeA[],  real chargeB[],
              rvec box,
              t_commrec *cr,   int natoms,
              matrix lrvir,    real ewaldcoeff,
              real lambda,     real *dvdlambda,
              struct gmx_ewald_tab_t *et)
{
    real     factor     = -1.0/(4*ewaldcoeff*ewaldcoeff);
    real     scaleRecip = 4.0*M_PI/(box[XX]*box[YY]*box[ZZ])*ONE_4PI_EPS0/ir->epsilon_r; /* 1/(Vol*e0) */
    real    *charge, energy_AB[2], energy;
    rvec     lll;
    int      lowiy, lowiz, ix, iy, iz, n, q;
    real     tmp, cs, ss, ak, akv, mx, my, mz, m2, scale;
    gmx_bool bFreeEnergy;

    if (cr != NULL)
    {
        if (PAR(cr))
        {
            gmx_fatal(FARGS, "No parallel Ewald. Use PME instead.\n");
        }
    }


    if (!et->eir) /* allocate if we need to */
    {
        snew(et->eir, et->kmax);
        for (n = 0; n < et->kmax; n++)
        {
            snew(et->eir[n], natoms);
        }
        snew(et->tab_xy, natoms);
        snew(et->tab_qxyz, natoms);
    }

    bFreeEnergy = (ir->efep != efepNO);

    clear_mat(lrvir);

    calc_lll(box, lll);
    /* make tables for the structure factor parts */
    tabulate_eir(natoms, x, et->kmax, et->eir, lll);

    for (q = 0; q < (bFreeEnergy ? 2 : 1); q++)
    {
        if (!bFreeEnergy)
        {
            charge = chargeA;
            scale  = 1.0;
        }
        else if (q == 0)
        {
            charge = chargeA;
            scale  = 1.0 - lambda;
        }
        else
        {
            charge = chargeB;
            scale  = lambda;
        }
        lowiy        = 0;
        lowiz        = 1;
        energy_AB[q] = 0;
        for (ix = 0; ix < et->nx; ix++)
        {
            mx = ix*lll[XX];
            for (iy = lowiy; iy < et->ny; iy++)
            {
                my = iy*lll[YY];
                if (iy >= 0)
                {
                    for (n = 0; n < natoms; n++)
                    {
                        et->tab_xy[n] = cmul(et->eir[ix][n][XX], et->eir[iy][n][YY]);
                    }
                }
                else
                {
                    for (n = 0; n < natoms; n++)
                    {
                        et->tab_xy[n] = conjmul(et->eir[ix][n][XX], et->eir[-iy][n][YY]);
                    }
                }
                for (iz = lowiz; iz < et->nz; iz++)
                {
                    mz  = iz*lll[ZZ];
                    m2  = mx*mx+my*my+mz*mz;
                    ak  = exp(m2*factor)/m2;
                    akv = 2.0*ak*(1.0/m2-factor);
                    if (iz >= 0)
                    {
                        for (n = 0; n < natoms; n++)
                        {
                            et->tab_qxyz[n] = rcmul(charge[n], cmul(et->tab_xy[n],
                                                                    et->eir[iz][n][ZZ]));
                        }
                    }
                    else
                    {
                        for (n = 0; n < natoms; n++)
                        {
                            et->tab_qxyz[n] = rcmul(charge[n], conjmul(et->tab_xy[n],
                                                                       et->eir[-iz][n][ZZ]));
                        }
                    }

                    cs = ss = 0;
                    for (n = 0; n < natoms; n++)
                    {
                        cs += et->tab_qxyz[n].re;
                        ss += et->tab_qxyz[n].im;
                    }
                    energy_AB[q]  += ak*(cs*cs+ss*ss);
                    tmp            = scale*akv*(cs*cs+ss*ss);
                    lrvir[XX][XX] -= tmp*mx*mx;
                    lrvir[XX][YY] -= tmp*mx*my;
                    lrvir[XX][ZZ] -= tmp*mx*mz;
                    lrvir[YY][YY] -= tmp*my*my;
                    lrvir[YY][ZZ] -= tmp*my*mz;
                    lrvir[ZZ][ZZ] -= tmp*mz*mz;
                    for (n = 0; n < natoms; n++)
                    {
                        /*tmp=scale*ak*(cs*tab_qxyz[n].im-ss*tab_qxyz[n].re);*/
                        tmp       = scale*ak*(cs*et->tab_qxyz[n].im-ss*et->tab_qxyz[n].re);
                        f[n][XX] += tmp*mx*2*scaleRecip;
                        f[n][YY] += tmp*my*2*scaleRecip;
                        f[n][ZZ] += tmp*mz*2*scaleRecip;
#if 0
                        f[n][XX] += tmp*mx;
                        f[n][YY] += tmp*my;
                        f[n][ZZ] += tmp*mz;
#endif
                    }
                    lowiz = 1-et->nz;
                }
                lowiy = 1-et->ny;
            }
        }
    }

    if (!bFreeEnergy)
    {
        energy = energy_AB[0];
    }
    else
    {
        energy      = (1.0 - lambda)*energy_AB[0] + lambda*energy_AB[1];
        *dvdlambda += scaleRecip*(energy_AB[1] - energy_AB[0]);
    }

    lrvir[XX][XX] = -0.5*scaleRecip*(lrvir[XX][XX]+energy);
    lrvir[XX][YY] = -0.5*scaleRecip*(lrvir[XX][YY]);
    lrvir[XX][ZZ] = -0.5*scaleRecip*(lrvir[XX][ZZ]);
    lrvir[YY][YY] = -0.5*scaleRecip*(lrvir[YY][YY]+energy);
    lrvir[YY][ZZ] = -0.5*scaleRecip*(lrvir[YY][ZZ]);
    lrvir[ZZ][ZZ] = -0.5*scaleRecip*(lrvir[ZZ][ZZ]+energy);

    lrvir[YY][XX] = lrvir[XX][YY];
    lrvir[ZZ][XX] = lrvir[XX][ZZ];
    lrvir[ZZ][YY] = lrvir[YY][ZZ];

    energy *= scaleRecip;

    return energy;
}
Пример #3
0
real do_ewald(FILE *log,       bool bVerbose,
	      t_inputrec *ir,
	      rvec x[],        rvec f[],
		  real charge[],   rvec box,
	      t_commrec *cr,	      t_nsborder *nsb,
	      matrix lrvir, real ewaldcoeff)
{
  static    bool bFirst = TRUE;
  static    int       nx,ny,nz,kmax;
  static    cvec      **eir;
  static    t_complex  *tab_xy,*tab_qxyz;
  real factor=-1.0/(4*ewaldcoeff*ewaldcoeff);
  real energy;
  rvec lll;
  int  lowiy,lowiz,ix,iy,iz,n;
  real tmp,cs,ss,ak,akv,mx,my,mz,m2;
  
  if (bFirst) {
      if (bVerbose)
    fprintf(log,"Will do ordinary reciprocal space Ewald sum.\n");

    if (cr != NULL) {
      if (cr->nnodes > 1 || cr->nthreads>1)
	fatal_error(0,"No parallel Ewald. Use PME instead.\n");
    }
    
    nx = ir->nkx+1;
    ny = ir->nky+1;
    nz = ir->nkz+1;
    kmax = max(nx,max(ny,nz));
    snew(eir,kmax);
    for(n=0;n<kmax;n++)
      snew(eir[n],HOMENR(nsb));
    snew(tab_xy,HOMENR(nsb));
    snew(tab_qxyz,HOMENR(nsb));
    bFirst = FALSE;
  }
  clear_mat(lrvir);
  
  calc_lll(box,lll);
  /* make tables for the structure factor parts */
  tabulate_eir(HOMENR(nsb),x,kmax,eir,lll);
  
  lowiy=0;
  lowiz=1;
  energy=0;
  for(ix=0;ix<nx;ix++) {
    mx=ix*lll[XX];
    for(iy=lowiy;iy<ny;iy++) {
      my=iy*lll[YY];
      if(iy>=0) 
	for(n=0;n<HOMENR(nsb);n++) 
	  tab_xy[n]=cmul(eir[ix][n][XX],eir[iy][n][YY]);
      else 
	for(n=0;n<HOMENR(nsb);n++) 
	  tab_xy[n]=conjmul(eir[ix][n][XX],eir[-iy][n][YY]); 
      for(iz=lowiz;iz<nz;iz++) {
	mz=iz*lll[ZZ];	       
	m2=mx*mx+my*my+mz*mz;
	ak=exp(m2*factor)/m2;
	akv=2.0*ak*(1.0/m2-factor);  
	if(iz>=0) 
	  for(n=0;n<HOMENR(nsb);n++) 
	    tab_qxyz[n]=rcmul(charge[n],cmul(tab_xy[n],eir[iz][n][ZZ]));
	else 
	  for(n=0;n<HOMENR(nsb);n++) 
	    tab_qxyz[n]=rcmul(charge[n],conjmul(tab_xy[n],eir[-iz][n][ZZ]));
            
	cs=ss=0;
	for(n=0;n<HOMENR(nsb);n++) {
	  cs+=tab_qxyz[n].re;
	  ss+=tab_qxyz[n].im;
	}
	energy+=ak*(cs*cs+ss*ss);
	tmp=akv*(cs*cs+ss*ss);	       
	lrvir[XX][XX]-=tmp*mx*mx;
	lrvir[XX][YY]-=tmp*mx*my;
	lrvir[XX][ZZ]-=tmp*mx*mz;
	lrvir[YY][YY]-=tmp*my*my;
	lrvir[YY][ZZ]-=tmp*my*mz;
	lrvir[ZZ][ZZ]-=tmp*mz*mz;
	for(n=0;n<HOMENR(nsb);n++) {
	  tmp=ak*(cs*tab_qxyz[n].im-ss*tab_qxyz[n].re);
	  f[n][XX]+=tmp*mx;
	  f[n][YY]+=tmp*my;
	  f[n][ZZ]+=tmp*mz;
	}
	lowiz=1-nz;
      }
      lowiy=1-ny;
    }
  }   
  tmp=4.0*M_PI/(box[XX]*box[YY]*box[ZZ])*ONE_4PI_EPS0;
  for(n=0;n<HOMENR(nsb);n++) {
    f[n][XX]*=2*tmp;
    f[n][YY]*=2*tmp;
    f[n][ZZ]*=2*tmp;
  }
  lrvir[XX][XX]=-0.5*tmp*(lrvir[XX][XX]+energy);
  lrvir[XX][YY]=-0.5*tmp*(lrvir[XX][YY]);
  lrvir[XX][ZZ]=-0.5*tmp*(lrvir[XX][ZZ]);
  lrvir[YY][YY]=-0.5*tmp*(lrvir[YY][YY]+energy);
  lrvir[YY][ZZ]=-0.5*tmp*(lrvir[YY][ZZ]);
  lrvir[ZZ][ZZ]=-0.5*tmp*(lrvir[ZZ][ZZ]+energy);
  
  lrvir[YY][XX]=lrvir[XX][YY];
  lrvir[ZZ][XX]=lrvir[XX][ZZ];
  lrvir[ZZ][YY]=lrvir[YY][ZZ];
  
  energy*=tmp;
  
  return energy;
}
Пример #4
0
real do_ewald(FILE *log,       bool bVerbose,
	      t_inputrec *ir,
	      rvec x[],        rvec f[],
	      real chargeA[],  real chargeB[],
	      rvec box,
	      t_commrec *cr,   int natoms,
	      matrix lrvir,    real ewaldcoeff,
	      real lambda,     real *dvdlambda)
{
  static    bool bFirst = TRUE;
  static    int       nx,ny,nz,kmax;
  static    cvec      **eir;
  static    t_complex  *tab_xy,*tab_qxyz;
  real factor=-1.0/(4*ewaldcoeff*ewaldcoeff);
  real *charge,energy_AB[2],energy;
  rvec lll;
  int  lowiy,lowiz,ix,iy,iz,n,q;
  real tmp,cs,ss,ak,akv,mx,my,mz,m2,scale;
  bool bFreeEnergy;

  bFreeEnergy = (ir->efep != efepNO);

  if (bFirst) {
      if (bVerbose)
    fprintf(log,"Will do ordinary reciprocal space Ewald sum.\n");

    if (cr != NULL) {
      if (cr->nnodes > 1 || cr->nthreads>1)
	gmx_fatal(FARGS,"No parallel Ewald. Use PME instead.\n");
    }
    
    nx = ir->nkx+1;
    ny = ir->nky+1;
    nz = ir->nkz+1;
    kmax = max(nx,max(ny,nz));
    snew(eir,kmax);
    for(n=0;n<kmax;n++)
      snew(eir[n],natoms);
    snew(tab_xy,natoms);
    snew(tab_qxyz,natoms);
    bFirst = FALSE;
  }
  clear_mat(lrvir);
  
  calc_lll(box,lll);
  /* make tables for the structure factor parts */
  tabulate_eir(natoms,x,kmax,eir,lll);

  for(q=0; q<(bFreeEnergy ? 2 : 1); q++) {
    if (!bFreeEnergy) {
      charge = chargeA;
      scale = 1.0;
    } else if (q==0) {
      charge = chargeA;
      scale = 1.0 - lambda;
    } else {
      charge = chargeB;
      scale = lambda;
    }
    lowiy=0;
    lowiz=1;
    energy_AB[q]=0;
    for(ix=0;ix<nx;ix++) {
      mx=ix*lll[XX];
      for(iy=lowiy;iy<ny;iy++) {
	my=iy*lll[YY];
	if(iy>=0) 
	  for(n=0;n<natoms;n++) 
	    tab_xy[n]=cmul(eir[ix][n][XX],eir[iy][n][YY]);
	else 
	  for(n=0;n<natoms;n++) 
	    tab_xy[n]=conjmul(eir[ix][n][XX],eir[-iy][n][YY]); 
	for(iz=lowiz;iz<nz;iz++) {
	  mz=iz*lll[ZZ];	       
	  m2=mx*mx+my*my+mz*mz;
	  ak=exp(m2*factor)/m2;
	  akv=2.0*ak*(1.0/m2-factor);  
	  if(iz>=0) 
	    for(n=0;n<natoms;n++) 
	      tab_qxyz[n]=rcmul(charge[n],cmul(tab_xy[n],eir[iz][n][ZZ]));
	  else 
	    for(n=0;n<natoms;n++) 
	      tab_qxyz[n]=rcmul(charge[n],conjmul(tab_xy[n],eir[-iz][n][ZZ]));
	  
	  cs=ss=0;
	  for(n=0;n<natoms;n++) {
	    cs+=tab_qxyz[n].re;
	    ss+=tab_qxyz[n].im;
	  }
	  energy_AB[q]+=ak*(cs*cs+ss*ss);
	  tmp=scale*akv*(cs*cs+ss*ss);	       
	  lrvir[XX][XX]-=tmp*mx*mx;
	  lrvir[XX][YY]-=tmp*mx*my;
	  lrvir[XX][ZZ]-=tmp*mx*mz;
	  lrvir[YY][YY]-=tmp*my*my;
	  lrvir[YY][ZZ]-=tmp*my*mz;
	  lrvir[ZZ][ZZ]-=tmp*mz*mz;
	  for(n=0;n<natoms;n++) {
	    tmp=scale*ak*(cs*tab_qxyz[n].im-ss*tab_qxyz[n].re);
	    f[n][XX]+=tmp*mx;
	    f[n][YY]+=tmp*my;
	    f[n][ZZ]+=tmp*mz;
	  }
	  lowiz=1-nz;
	}
	lowiy=1-ny;
      }
    }
  }
  
  tmp=4.0*M_PI/(box[XX]*box[YY]*box[ZZ])*ONE_4PI_EPS0/ir->epsilon_r;

  if (!bFreeEnergy) {
    energy = energy_AB[0];
  } else {
    energy = (1.0 - lambda)*energy_AB[0] + lambda*energy_AB[1];
    *dvdlambda += tmp*(energy_AB[1] - energy_AB[0]);
  }
  for(n=0;n<natoms;n++) {
    f[n][XX]*=2*tmp;
    f[n][YY]*=2*tmp;
    f[n][ZZ]*=2*tmp;
  }
  lrvir[XX][XX]=-0.5*tmp*(lrvir[XX][XX]+energy);
  lrvir[XX][YY]=-0.5*tmp*(lrvir[XX][YY]);
  lrvir[XX][ZZ]=-0.5*tmp*(lrvir[XX][ZZ]);
  lrvir[YY][YY]=-0.5*tmp*(lrvir[YY][YY]+energy);
  lrvir[YY][ZZ]=-0.5*tmp*(lrvir[YY][ZZ]);
  lrvir[ZZ][ZZ]=-0.5*tmp*(lrvir[ZZ][ZZ]+energy);
  
  lrvir[YY][XX]=lrvir[XX][YY];
  lrvir[ZZ][XX]=lrvir[XX][ZZ];
  lrvir[ZZ][YY]=lrvir[YY][ZZ];
  
  energy*=tmp;
  
  return energy;
}