Esempio n. 1
0
 static double de_atof(std::string s) {
   string r = d2e(s);
   //double rval = Cantera::atofCheck(r.c_str()); 
   double rval = atof(r.c_str());
   return rval;
 }
Esempio n. 2
0
void do_coupling(FILE *log,int nfile,t_filenm fnm[],
		 t_coupl_rec *tcr,real t,int step,real ener[],
		 t_forcerec *fr,t_inputrec *ir,bool bMaster,
		 t_mdatoms *md,t_idef *idef,real mu_aver,int nmols,
		 t_commrec *cr,matrix box,tensor virial,
		 tensor pres,rvec mu_tot,
		 rvec x[],rvec f[],bool bDoIt)
{
#define enm2Debye 48.0321
#define d2e(x) (x)/enm2Debye
#define enm2kjmol(x) (x)*0.0143952 /* = 2.0*4.0*M_PI*EPSILON0 */

  static real *f6,*f12,*fa,*fb,*fc,*fq;
  static bool bFirst = TRUE;
  
  int         i,j,ati,atj,atnr2,type,ftype;
  real        deviation[eoObsNR],prdev[eoObsNR],epot0,dist,rmsf;
  real        ff6,ff12,ffa,ffb,ffc,ffq,factor,dt,mu_ind;
  real        Epol,Eintern,Virial,muabs,xiH=-1,xiS=-1,xi6,xi12;
  rvec        fmol[2];
  bool        bTest,bPrint;
  t_coupl_LJ  *tclj;
  t_coupl_BU  *tcbu;
  t_coupl_Q   *tcq;
  t_coupl_iparams *tip;
  
  atnr2 = idef->atnr * idef->atnr;
  if (bFirst) {
    if (PAR(cr))
      fprintf(log,"GCT: this is parallel\n");
    else
      fprintf(log,"GCT: this is not parallel\n");
    fflush(log);
    snew(f6, atnr2);
    snew(f12,atnr2);
    snew(fa, atnr2);
    snew(fb, atnr2);
    snew(fc, atnr2);
    snew(fq, idef->atnr);
    
    if (tcr->bVirial) {
      int  nrdf = 0;
      real TTT  = 0;
      real Vol  = det(box);
      
      for(i=0; (i<ir->opts.ngtc); i++) {
	nrdf += ir->opts.nrdf[i];
	TTT  += ir->opts.nrdf[i]*ir->opts.ref_t[i];
      }
      TTT /= nrdf;
      
      /* Calculate reference virial from reference temperature and pressure */
      tcr->ref_value[eoVir] = 0.5*BOLTZ*nrdf*TTT - (3.0/2.0)*
	Vol*tcr->ref_value[eoPres];
      
      fprintf(log,"GCT: TTT = %g, nrdf = %d, vir0 = %g,  Vol = %g\n",
	      TTT,nrdf,tcr->ref_value[eoVir],Vol);
      fflush(log);
    }
    bFirst = FALSE;
  }
  
  bPrint = MASTER(cr) && do_per_step(step,ir->nstlog);
  dt     = ir->delta_t;

  /* Initiate coupling to the reference pressure and temperature to start
   * coupling slowly.
   */
  if (step == 0) {
    for(i=0; (i<eoObsNR); i++)
      tcr->av_value[i] = tcr->ref_value[i];
    if ((tcr->ref_value[eoDipole]) != 0.0) {
      mu_ind = mu_aver - d2e(tcr->ref_value[eoDipole]); /* in e nm */
      Epol   = mu_ind*mu_ind/(enm2kjmol(tcr->ref_value[eoPolarizability]));
      tcr->av_value[eoEpot] -= Epol;
      fprintf(log,"GCT: mu_aver = %g(D), mu_ind = %g(D), Epol = %g (kJ/mol)\n",
	      mu_aver*enm2Debye,mu_ind*enm2Debye,Epol);
    }
  }

  /* We want to optimize the LJ params, usually to the Vaporization energy 
   * therefore we only count intermolecular degrees of freedom.
   * Note that this is now optional. switch UseEinter to yes in your gct file
   * if you want this.
   */
  dist      = calc_dist(log,x);
  muabs     = norm(mu_tot);
  Eintern   = Ecouple(tcr,ener)/nmols;
  Virial    = virial[XX][XX]+virial[YY][YY]+virial[ZZ][ZZ];

  /*calc_force(md->nr,f,fmol);*/
  clear_rvec(fmol[0]);
  
  /* Use a memory of tcr->nmemory steps, so we actually couple to the
   * average observable over the last tcr->nmemory steps. This may help
   * in avoiding local minima in parameter space.
   */
  set_act_value(tcr,eoPres, ener[F_PRES],step);
  set_act_value(tcr,eoEpot, Eintern,     step);
  set_act_value(tcr,eoVir,  Virial,      step);
  set_act_value(tcr,eoDist, dist,        step);
  set_act_value(tcr,eoMu,   muabs,       step);
  set_act_value(tcr,eoFx,   fmol[0][XX], step);
  set_act_value(tcr,eoFy,   fmol[0][YY], step);
  set_act_value(tcr,eoFz,   fmol[0][ZZ], step);
  set_act_value(tcr,eoPx,   pres[XX][XX],step);
  set_act_value(tcr,eoPy,   pres[YY][YY],step);
  set_act_value(tcr,eoPz,   pres[ZZ][ZZ],step);
  
  epot0 = tcr->ref_value[eoEpot];
  /* If dipole != 0.0 assume we want to use polarization corrected coupling */
  if ((tcr->ref_value[eoDipole]) != 0.0) {
    mu_ind = mu_aver - d2e(tcr->ref_value[eoDipole]); /* in e nm */
    
    Epol = mu_ind*mu_ind/(enm2kjmol(tcr->ref_value[eoPolarizability]));
    
    epot0 -= Epol;
    if (debug) {
      fprintf(debug,"mu_ind: %g (%g D) mu_aver: %g (%g D)\n",
	      mu_ind,mu_ind*enm2Debye,mu_aver,mu_aver*enm2Debye);
      fprintf(debug,"Eref %g Epol %g Erunav %g Eact %g\n",
	      tcr->ref_value[eoEpot],Epol,tcr->av_value[eoEpot],
	      tcr->act_value[eoEpot]);
    }
  }

  if (bPrint) {
    pr_ff(tcr,t,idef,cr,nfile,fnm);
  }
  /* Calculate the deviation of average value from the target value */
  for(i=0; (i<eoObsNR); i++) {
    deviation[i] = calc_deviation(tcr->av_value[i],tcr->act_value[i],
				  tcr->ref_value[i]);
    prdev[i]     = tcr->ref_value[i] - tcr->act_value[i];
  }
  deviation[eoEpot] = calc_deviation(tcr->av_value[eoEpot],tcr->act_value[eoEpot],
				     epot0);
  prdev[eoEpot]     = epot0 - tcr->act_value[eoEpot];
  
  if (bPrint)
    pr_dev(tcr,t,prdev,cr,nfile,fnm);
  
  /* First set all factors to 1 */
  for(i=0; (i<atnr2); i++) {
    f6[i] = f12[i] = fa[i] = fb[i] = fc[i] = 1.0;
  }
  for(i=0; (i<idef->atnr); i++) 
    fq[i] = 1.0;

  /* Now compute the actual coupling compononents */   
  if (!fr->bBHAM) {
    if (bDoIt) {
      for(i=0; (i<tcr->nLJ); i++) {
	tclj=&(tcr->tcLJ[i]);
	
	ati=tclj->at_i;
	atj=tclj->at_j;
	
	ff6 = ff12 = 1.0;	
	
	if (tclj->eObs == eoForce) {
	  gmx_fatal(FARGS,"Hack code for this to work again ");
	  if (debug)
	    fprintf(debug,"Have computed derivatives: xiH = %g, xiS = %g\n",xiH,xiS);
	  if (ati == 1) {
	    /* Hydrogen */
	    ff12 += xiH; 
	  }
	  else if (ati == 2) {
	    /* Shell */
	    ff12 += xiS; 
	  }
	  else
	    gmx_fatal(FARGS,"No H, no Shell, edit code at %s, line %d\n",
			__FILE__,__LINE__);
	  if (ff6 > 0)
	    set_factor_matrix(idef->atnr,f6, sqrt(ff6), ati,atj);
	  if (ff12 > 0)
	    set_factor_matrix(idef->atnr,f12,sqrt(ff12),ati,atj);
	}
	else {
	  if (debug)
	    fprintf(debug,"tcr->tcLJ[%d].xi_6 = %g, xi_12 = %g deviation = %g\n",i,
		    tclj->xi_6,tclj->xi_12,deviation[tclj->eObs]);
	  factor=deviation[tclj->eObs];
	  
	  upd_f_value(log,idef->atnr,tclj->xi_6, dt,factor,f6, ati,atj);
	  upd_f_value(log,idef->atnr,tclj->xi_12,dt,factor,f12,ati,atj);
	}
      }
    }
    if (PAR(cr)) {
      gprod(cr,atnr2,f6);
      gprod(cr,atnr2,f12);
#ifdef DEBUGGCT
      dump_fm(log,idef->atnr,f6,"f6");
      dump_fm(log,idef->atnr,f12,"f12");
#endif
    }
    upd_nbfplj(log,fr->nbfp,idef->atnr,f6,f12,tcr->combrule);
    
    /* Copy for printing */
    for(i=0; (i<tcr->nLJ); i++) {
      tclj=&(tcr->tcLJ[i]);
      ati = tclj->at_i;
      atj = tclj->at_j;
      if (atj == -1) 
	atj = ati;
      tclj->c6  =  C6(fr->nbfp,fr->ntype,ati,atj);
      tclj->c12 = C12(fr->nbfp,fr->ntype,ati,atj);
    }
  }
  else {
    if (bDoIt) {
      for(i=0; (i<tcr->nBU); i++) {
	tcbu   = &(tcr->tcBU[i]);
	factor = deviation[tcbu->eObs];
	ati    = tcbu->at_i;
	atj    = tcbu->at_j;
	
	upd_f_value(log,idef->atnr,tcbu->xi_a,dt,factor,fa,ati,atj);
	upd_f_value(log,idef->atnr,tcbu->xi_b,dt,factor,fb,ati,atj);
	upd_f_value(log,idef->atnr,tcbu->xi_c,dt,factor,fc,ati,atj);
      }
    }
    if (PAR(cr)) {
      gprod(cr,atnr2,fa);
      gprod(cr,atnr2,fb);
      gprod(cr,atnr2,fc);
    }
    upd_nbfpbu(log,fr->nbfp,idef->atnr,fa,fb,fc);
    /* Copy for printing */
    for(i=0; (i<tcr->nBU); i++) {
      tcbu=&(tcr->tcBU[i]);
      ati = tcbu->at_i;
      atj = tcbu->at_j;
      if (atj == -1) 
	atj = ati;
      tcbu->a = BHAMA(fr->nbfp,fr->ntype,ati,atj);
      tcbu->b = BHAMB(fr->nbfp,fr->ntype,ati,atj);
      tcbu->c = BHAMC(fr->nbfp,fr->ntype,ati,atj);
      if (debug)
	fprintf(debug,"buck (type=%d) = %e, %e, %e\n",
		tcbu->at_i,tcbu->a,tcbu->b,tcbu->c);
    }
  }
  if (bDoIt) {
    for(i=0; (i<tcr->nQ); i++) {
      tcq=&(tcr->tcQ[i]);
      if (tcq->xi_Q)     
	ffq = 1.0 + (dt/tcq->xi_Q) * deviation[tcq->eObs];
      else
	ffq = 1.0;
      fq[tcq->at_i] *= ffq;
    }
  }
  if (PAR(cr))
    gprod(cr,idef->atnr,fq);
  
  for(j=0; (j<md->nr); j++) {
    md->chargeA[j] *= fq[md->typeA[j]];
  }
  for(i=0; (i<tcr->nQ); i++) {
    tcq=&(tcr->tcQ[i]);
    for(j=0; (j<md->nr); j++) {
      if (md->typeA[j] == tcq->at_i) {
	tcq->Q = md->chargeA[j];
	break;
      }
    }
    if (j == md->nr)
      gmx_fatal(FARGS,"Coupling type %d not found",tcq->at_i);
  }  
  for(i=0; (i<tcr->nIP); i++) {
    tip    = &(tcr->tIP[i]);
    type   = tip->type;
    ftype  = idef->functype[type];
    factor = dt*deviation[tip->eObs];
      
    switch(ftype) {
    case F_BONDS:
      if (tip->xi.harmonic.krA) idef->iparams[type].harmonic.krA *= (1+factor/tip->xi.harmonic.krA);
      if (tip->xi.harmonic.rA) idef->iparams[type].harmonic.rA *= (1+factor/tip->xi.harmonic.rA);
	break;
    default:
      break;
    }
    tip->iprint=idef->iparams[type];
  }
}