⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disprep.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
字号:
#ifdef HAVE_CONFIG_H#include <scconfig.h>#endif#include <fstream>#include <util/keyval/keyval.h>#include <math/isosurf/shape.h>#include <chemistry/qc/wfn/solvent.h>#include <chemistry/molecule/formula.h>#ifdef USING_NAMESPACE_STDusing namespace std;#endifusing namespace sc;static inline doubleget_ki(int z){  // The ki values (used in the computation of the dispersion coefficients)  // for H, C, and N were taken from Vigne-Maeder and Claverie, JACS 1987, v109, pp24-28  // and the value for O from Huron and Claverie, J. Phys. Chem. 1974, v78, p1862  double ki;    if (z <= 0) {      ExEnv::errn() << "Non-positive nuclear charge encountered in computation of"           << " dispersion coefficient" << endl;      abort();    }  else if (z == 1) ki = 1.0;  else if (z == 6) ki = 1.0;  else if (z == 7) ki = 1.18;  else if (z == 8) ki = 1.36;  // from Huron & Claverie, J.Phys.Chem v78, 1974, p1862  else if (z > 1 && z < 6) {      ki = 1.0;      ExEnv::out0() << "Warning: No d6 dispersion coefficient available for atomic number " <<              z << "; using value for carbon instead" << endl;    }  else {      ki = 1.18;      ExEnv::out0() << "Warning: No d6 dispersion coefficient available for atomic number " <<              z << "; using value for nitrogen instead" << endl;    }    return ki;}static inline doubleget_d6ii(int z, double r_vdw){  // The dispersion coefficient d6 for a pair of atoms ij can be computed  // from the dispersion coefficient d6ii for atom pair ii and d6jj for  // atom pair jj by the formula: d6 = sqrt(d6ii*d6jj).  // The dispersion coefficients d8 and d10 can be obtained from d6.  // The d6ii values given below were taken from: Vigne-Maeder and Claverie  // JACS 1987, v. 109, pp. 24-28.  const double a6 = 0.143; // [kcal/mol]  double d6ii;  double ki;  Ref<Units> unit = new Units("kcal/mol");    ki = get_ki(z);  d6ii = ki*ki*a6*pow(4*r_vdw*r_vdw,3.0);  // units of (kcal mol^-1)*bohr^6  d6ii *= unit->to_atomic_units();  // convert to atomic units  return d6ii;}static inline doubleget_d8ii(double d6ii, double r_vdw){  // The value of c8 was taken from Vigne-Maeder and Claverie, JACS 1987,  // v. 109, pp 24-28 and is here obtained in atomic units by using  // atomic units for d6ii and r_vdw  double d8ii;  const double c8 = 0.26626;  d8ii = d6ii*c8*4*pow(r_vdw,2.0);    return d8ii;}static inline doubleget_d10ii(double d6ii, double r_vdw){  // The value of c10 was taken from Vigne-Maeder and Claverie, JACS 1987,  // v. 109, pp 24-28 and is here obtained in atomic units by using  // atomic units for d6ii and r_vdw  double d10ii;  const double c10 = 0.095467;  d10ii = d6ii*c10*16*pow(r_vdw,4.0);    return d10ii;}// For debugging compute 6, 8, and 10 contributions separatelystatic inline doubledisp6_contrib(double rasnorm, double d6){  double edisp6_contrib;  edisp6_contrib = d6/(3*pow(rasnorm,6.0)); // atomic units    return edisp6_contrib;}static inline doubledisp8_contrib(double rasnorm, double d8){  double edisp8_contrib;  edisp8_contrib = d8/(5*pow(rasnorm,8.0)); // atomic units    return edisp8_contrib;}static inline doubledisp10_contrib(double rasnorm, double d10){  double edisp10_contrib;  edisp10_contrib = d10/(7*pow(rasnorm,10.0)); // atomic units    return edisp10_contrib;}static inline doubledisp_contrib(double rasnorm, double d6, double d8, double d10){  double edisp_contrib;  edisp_contrib = d6/(3*pow(rasnorm,6.0)) + d8/(5*pow(rasnorm,8.0))                + d10/(7*pow(rasnorm,10.0));    return edisp_contrib;}static inline doublerep_contrib(double rasnorm, double ri_vdw, double rj_vdw, double ki, double kj,            double kcalpermol_to_hartree){  // The expression and the parameters used for the repulsion energy  // were taken from Vigne-Maeder and Claverie, JACS 1987, v109, pp24-28  // NB: We have omitted the factor Gij    const double c = 90000; // [kcal/mol]  const double gamma = 12.35;  double erep_contrib;  double tmp;    tmp = gamma*rasnorm/(2.0*sqrt(ri_vdw*rj_vdw));  erep_contrib = -ki*kj*c*(1.0/tmp + 2.0/(tmp*tmp) + 2.0/(tmp*tmp*tmp))*exp(-tmp);  erep_contrib *= kcalpermol_to_hartree; // convert from kcal/mol to atomic units    return erep_contrib;}doubleBEMSolvent::disprep() {  double edisprep = 0.0;  double edisprep_contrib;  double edisp6_contrib, edisp8_contrib, edisp10_contrib; // for debugging  double erep_contrib;  double edisp6 = 0.0; // for debugging  double edisp8 = 0.0; // for debugging  double edisp10 = 0.0; // for debugging  double erep = 0.0;  double proberadius;  double radius;  double rasnorm;  double weight;  double d6, d8, d10; // dispersion coefficients  double d6aa, d8aa, d10aa; // dispersion coefficients for atom pair aa  double d6ss, d8ss, d10ss; // dispersion coefficients for atom pair ss  int i, iloop, isolute;  int natomtypes;  int z_solvent_atom;  Ref<Units> unit = new Units("kcal/mol");  double kcalpermol_to_hartree = unit->to_atomic_units();  Ref<AtomInfo> atominfo = solute_->atominfo();  Ref<AtomInfo> solventatominfo = solvent_->atominfo();  MolecularFormula formula(solvent_);  // Compute number of different atom types in solvent molecule  natomtypes = formula.natomtypes();  double *solute_d6ii  = new double[solute_->natom()];  double *solute_d8ii  = new double[solute_->natom()];  double *solute_d10ii = new double[solute_->natom()];  double *solute_ki = new double[solute_->natom()];  for (isolute=0; isolute<solute_->natom(); isolute++) {      int Z_solute = solute_->Z(isolute);      double radius = atominfo->vdw_radius(Z_solute);      solute_d6ii[isolute] = get_d6ii(Z_solute,radius);      solute_d8ii[isolute] = get_d8ii(solute_d6ii[isolute],radius);      solute_d10ii[isolute] = get_d10ii(solute_d6ii[isolute],radius);      solute_ki[isolute] = get_ki(Z_solute);    }    // Loop over atom types in solvent molecule  for (iloop=0; iloop<natomtypes; iloop++) {      // define the shape of the surface for current atom type      Ref<UnionShape> us = new UnionShape;      z_solvent_atom = formula.Z(iloop);      proberadius = solventatominfo->vdw_radius(z_solvent_atom);      for (i=0; i<solute_->natom(); i++) {          us->add_shape(new SphereShape(solute_->r(i),                                        atominfo->vdw_radius(solute_->Z(i))+proberadius));        }            // triangulate the surface      Ref<AssignedKeyVal> keyval = new AssignedKeyVal;      keyval->assign("volume", us.pointer());      keyval->assign("order", 2);      keyval->assign("remove_short_edges", 1);      keyval->assign("remove_small_triangles", 1);      keyval->assign("remove_slender_triangles", 1);      keyval->assign("short_edge_factor", 0.8);      keyval->assign("small_triangle_factor", 0.8);      keyval->assign("slender_triangle_factor", 0.8);      Ref<TriangulatedImplicitSurface> ts = new TriangulatedImplicitSurface(keyval.pointer());      ts->init();      // Debug print: check the triangulated surface//      if (iloop == 0) {//          ofstream geomviewfile("geomview.input");//          ts->print_geomview_format(geomviewfile);//        }            ExEnv::out0().setf(ios::scientific,ios::floatfield); // use scientific format      ExEnv::out0() << "Area of disp-rep surface generated with atom number "           << setw(3) << setfill(' ') << z_solvent_atom           << " as probe: " << setprecision(4) << ts->area()           << " bohr^2" << endl;            edisprep_contrib = 0.0;      edisp6_contrib = 0.0;  // for debugging      edisp8_contrib = 0.0;  // for debugging      edisp10_contrib = 0.0; // for debugging      erep_contrib = 0.0;      TriangulatedSurfaceIntegrator triint(ts.pointer());      double solvent_ki = get_ki(z_solvent_atom);      d6ss = get_d6ii(z_solvent_atom,proberadius);      d8ss = get_d8ii(d6ss, proberadius);      d10ss = get_d10ii(d6ss, proberadius);                    // integrate the surface      for (triint=0; triint.update(); triint++) {          SCVector3 dA = triint.dA();          SCVector3 location = triint.current()->point();          weight = triint.weight();                    //Loop over atoms in solute          for (isolute=0; isolute<solute_->natom(); isolute++) {              SCVector3 atom(solute_->r(isolute));               SCVector3 ras = location - atom;              rasnorm = ras.norm();              radius = atominfo->vdw_radius(solute_->Z(isolute));              d6aa = solute_d6ii[isolute];              d8aa = solute_d8ii[isolute];              d10aa = solute_d10ii[isolute];              d6 = sqrt(d6aa*d6ss);              d8 = sqrt(d8aa*d8ss);              d10 = sqrt(d10aa*d10ss);              double f = ras.dot(dA)*weight;              double tdisp6 = f*disp6_contrib(rasnorm,d6);              double tdisp8 = f*disp8_contrib(rasnorm,d8);              double tdisp10 = f*disp10_contrib(rasnorm,d10);              double trep = f*rep_contrib(rasnorm,radius,proberadius,                                          solute_ki[isolute],solvent_ki,                                          kcalpermol_to_hartree);              double tdisp = tdisp6+tdisp8+tdisp10;              // add in contributions to various energies; the minus sign              // is there to get the normal pointing into the cavity              edisprep_contrib -= tdisp+trep;              edisp6_contrib -= tdisp6;              edisp8_contrib -= tdisp8;              edisp10_contrib -= tdisp10;              erep_contrib -= trep;                          }        }            edisprep += edisprep_contrib*formula.nZ(iloop);      edisp6 += edisp6_contrib*formula.nZ(iloop);      edisp8 += edisp8_contrib*formula.nZ(iloop);      edisp10 += edisp10_contrib*formula.nZ(iloop);      erep += erep_contrib*formula.nZ(iloop);    }  delete[] solute_d6ii;  delete[] solute_d8ii;  delete[] solute_d10ii;  delete[] solute_ki;  // Multiply energies by number density of solvent  // Print out individual energy contributions in kcal/mol    ExEnv::out0().setf(ios::scientific,ios::floatfield); // use scientific format  ExEnv::out0().precision(5);  ExEnv::out0() << "Edisp6:  " << edisp6*solvent_density_*unit->from_atomic_units()       << " kcal/mol" << endl;   ExEnv::out0() << "Edisp8:  " << edisp8*solvent_density_*unit->from_atomic_units()       << " kcal/mol" << endl;  ExEnv::out0() << "Edisp10: " << edisp10*solvent_density_*unit->from_atomic_units()       << " kcal/mol" << endl;  ExEnv::out0() << "Total dispersion energy: "       << (edisp6 + edisp8 + edisp10)*solvent_density_*unit->from_atomic_units()       << " kcal/mol" << endl;  ExEnv::out0() << "Repulsion energy:        " << setw(12) << setfill(' ')        << erep*solvent_density_*unit->from_atomic_units() << " kcal/mol" << endl;    return edisprep*solvent_density_; // atomic units}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -