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

📄 integrator.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
📖 第 1 页 / 共 5 页
字号:
  double densij;  double bvi, bvix, bviy, bviz;  double bvixx, bviyx, bviyy, bvizx, bvizy, bvizz;  const int X = PointInputData::X;  const int Y = PointInputData::Y;  const int Z = PointInputData::Z;  const int XX = PointInputData::XX;  const int YX = PointInputData::YX;  const int YY = PointInputData::YY;  const int ZX = PointInputData::ZX;  const int ZY = PointInputData::ZY;  const int ZZ = PointInputData::ZZ;  double grad[3], hess[6];  if (need_gradient_) for (i=0; i<3; i++) grad[i] = 0.0;  if (need_hessian_) for (i=0; i<6; i++) hess[i] = 0.0;  CHECK_ALIGN(tmp);  CHECK_ALIGN(grad[0]);  if (need_gradient_) {      for (i=0; i < ncontrib_bf_; i++) {          int it = contrib_bf_[i];          bvi = bs_values_[i];          if (need_gradient_) {              bvix = bsg_values_[i*3+X];              bviy = bsg_values_[i*3+Y];              bviz = bsg_values_[i*3+Z];            }          if (need_hessian_) {              bvixx = bsh_values_[i*6+XX];              bviyx = bsh_values_[i*6+YX];              bviyy = bsh_values_[i*6+YY];              bvizx = bsh_values_[i*6+ZX];              bvizy = bsh_values_[i*6+ZY];              bvizz = bsh_values_[i*6+ZZ];            }          int j3 = 0, j6 = 0;          int itoff = (it*(it+1))>>1;          int itjt;          double t = 0.0;          for (j=0; j < i; j++) {              int jt = contrib_bf_[j];              itjt = itoff+jt;              densij = dmat[itjt];              double bvj = bs_values_[j];              CHECK_ALIGN(densij);              CHECK_ALIGN(bvj);              t += densij*bvi*bvj;              double bvjx, bvjy, bvjz;              if (need_gradient_) {                  bvjx = bsg_values_[j3+X];                  bvjy = bsg_values_[j3+Y];                  bvjz = bsg_values_[j3+Z];                  grad[X] += densij*(bvi*bvjx + bvj*bvix);                  grad[Y] += densij*(bvi*bvjy + bvj*bviy);                  grad[Z] += densij*(bvi*bvjz + bvj*bviz);                  j3 += 3;                }              if (need_hessian_) {                  double bvjxx = bsh_values_[j6+XX];                  double bvjyx = bsh_values_[j6+YX];                  double bvjyy = bsh_values_[j6+YY];                  double bvjzx = bsh_values_[j6+ZX];                  double bvjzy = bsh_values_[j6+ZY];                  double bvjzz = bsh_values_[j6+ZZ];                  hess[XX] += densij*(bvi*bvjxx+bvix*bvjx+bvjx*bvix+bvixx*bvj);                  hess[YX] += densij*(bvi*bvjyx+bviy*bvjx+bvjy*bvix+bviyx*bvj);                  hess[YY] += densij*(bvi*bvjyy+bviy*bvjy+bvjy*bviy+bviyy*bvj);                  hess[ZX] += densij*(bvi*bvjzx+bviz*bvjx+bvjz*bvix+bvizx*bvj);                  hess[ZY] += densij*(bvi*bvjzy+bviz*bvjy+bvjz*bviy+bvizy*bvj);                  hess[ZZ] += densij*(bvi*bvjzz+bviz*bvjz+bvjz*bviz+bvizz*bvj);                  j6 += 6;                }            }          densij = dmat[itoff+it]*bvi;          tmp += t + 0.5*densij*bvi;          if (need_gradient_) {              grad[X] += densij*bvix;              grad[Y] += densij*bviy;              grad[Z] += densij*bviz;            }          if (need_hessian_) {              hess[XX] += densij*bvixx;              hess[YX] += densij*bviyx;              hess[YY] += densij*bviyy;              hess[ZX] += densij*bvizx;              hess[ZY] += densij*bvizy;              hess[ZZ] += densij*bvizz;            }        }    }  else {      for (i=0; i < ncontrib_bf_; i++) {          int it = contrib_bf_[i];          bvi = bs_values_[i];          int itoff = (it*(it+1))>>1;          int itjt;          double t = 0.0;          for (j=0; j < i; j++) {              int jt = contrib_bf_[j];              itjt = itoff+jt;              densij = dmat[itjt];              double bvj = bs_values_[j];              CHECK_ALIGN(densij);              CHECK_ALIGN(bvj);              t += densij*bvi*bvj;            }          densij = dmat[itoff+it]*bvi;          tmp += t + 0.5*densij*bvi;        }    }  d.rho = 2.0 * tmp;  if (need_gradient_) {      for (i=0; i<3; i++) d.del_rho[i] = 2.0 * grad[i];      d.gamma = dot(d.del_rho,d.del_rho);    }  if (need_hessian_) {      for (i=0; i<6; i++) d.hes_rho[i] = 2.0 * hess[i];      d.lap_rho = d.hes_rho[XX] + d.hes_rho[YY] + d.hes_rho[ZZ];    }}doubleDenIntegratorThread::do_point(int acenter, const SCVector3 &r,                        double weight, double multiplier,                        double *nuclear_gradient,                        double *f_gradient, double *w_gradient){  int i,j;  double w_mult = weight * multiplier;  CHECK_ALIGN(w_mult);  // only consider those shells for which phi_i * (Max_j D_ij phi_j) > tol  if (linear_scaling_ && use_dmat_bound_) {      const std::vector<ExtentData> &cs = extent_->contributing_shells(r[0],r[1],r[2]);      ncontrib_ = 0;      for (i=0; i<cs.size(); i++) {          int ish = cs[i].shell;          int contrib = 0;          for (j=0; j<cs.size(); j++) {              int jsh = cs[j].shell;              int ijsh = (ish>jsh)?((ish*(ish+1))/2+jsh):((jsh*(jsh+1))/2+ish);              if (cs[i].bound*cs[j].bound*dmat_bound_[ijsh] > 0.00001*accuracy_) {                  contrib = 1;                  break;                }            }          if (contrib) {              contrib_[ncontrib_++] = ish;            }        }    }  else if (linear_scaling_) {      const std::vector<ExtentData> &cs = extent_->contributing_shells(r[0],r[1],r[2]);      ncontrib_ = cs.size();      for (i=0; i<ncontrib_; i++) {          contrib_[i] = cs[i].shell;        }    }  else {      ncontrib_ = nshell_;      for (i=0; i<nshell_; i++) contrib_[i] = i;    }  if (ncontrib_ > nshell_) {      ExEnv::outn() << "DenIntegratorThread::do_point: ncontrib invalid"                   << endl;      abort();    }  ncontrib_bf_ = 0;  for (i=0; i<ncontrib_; i++) {      int nbf = basis_->shell(contrib_[i]).nfunction();      int bf = basis_->shell_to_function(contrib_[i]);      for (j=0; j<nbf; j++, bf++) {          contrib_bf_[ncontrib_bf_++] = bf;        }    }  // compute the basis set values  double *bsh = bsh_values_, *bsg = bsg_values_, *bsv = bs_values_;  for (i=0; i<ncontrib_; i++) {      basis_->hessian_shell_values(r,contrib_[i],valdat_,bsh,bsg,bsv);      int shsize = basis_->shell(contrib_[i]).nfunction();      if (bsh) bsh += 6 * shsize;      if (bsg) bsg += 3 * shsize;      if (bsv) bsv += shsize;    }  // loop over basis functions adding contributions to the density  PointInputData id(r);  get_density(alpha_dmat_, id.a);  if (spin_polarized_) {      get_density(beta_dmat_, id.b);      if (need_gradient_) {          id.gamma_ab = id.a.del_rho[0]*id.b.del_rho[0]                      + id.a.del_rho[1]*id.b.del_rho[1]                       + id.a.del_rho[2]*id.b.del_rho[2];        }    }  id.compute_derived(spin_polarized_, need_gradient_);  PointOutputData od;  if ( (id.a.rho + id.b.rho) > 1e2*DBL_EPSILON) {      if (nuclear_gradient == 0) {          func_->point(id, od);        }      else {          func_->gradient(id, od, f_gradient, acenter, basis_,                         alpha_dmat_, (spin_polarized_?beta_dmat_:alpha_dmat_),                         ncontrib_, contrib_, ncontrib_bf_, contrib_bf_,                         bs_values_, bsg_values_, bsh_values_);        }    }  else {      return id.a.rho + id.b.rho;    }    value_ += od.energy * w_mult;  if (compute_potential_integrals_) {      // the contribution to the potential integrals      if (need_gradient_) {          double gradsa[3], gradsb[3];          gradsa[0] = w_mult*(2.0*od.df_dgamma_aa*id.a.del_rho[0] +                                  od.df_dgamma_ab*id.b.del_rho[0]);          gradsa[1] = w_mult*(2.0*od.df_dgamma_aa*id.a.del_rho[1] +                                 od.df_dgamma_ab*id.b.del_rho[1]);          gradsa[2] = w_mult*(2.0*od.df_dgamma_aa*id.a.del_rho[2] +                                  od.df_dgamma_ab*id.b.del_rho[2]);          double drhoa = w_mult*od.df_drho_a, drhob=0.0;          if (spin_polarized_) {              drhob = w_mult*od.df_drho_b;              gradsb[0] = w_mult*(2.0*od.df_dgamma_bb*id.b.del_rho[0] +                                      od.df_dgamma_ab*id.a.del_rho[0]);              gradsb[1] = w_mult*(2.0*od.df_dgamma_bb*id.b.del_rho[1] +                                      od.df_dgamma_ab*id.a.del_rho[1]);              gradsb[2] = w_mult*(2.0*od.df_dgamma_bb*id.b.del_rho[2] +                                      od.df_dgamma_ab*id.a.del_rho[2]);            }          for (int j=0; j<ncontrib_bf_; j++) {              int jt = contrib_bf_[j];              double dfdra_phi_m = drhoa*bs_values_[j];              double dfdga_phi_m = gradsa[0]*bsg_values_[j*3+0] +                                   gradsa[1]*bsg_values_[j*3+1] +                                   gradsa[2]*bsg_values_[j*3+2];              double vamu = dfdra_phi_m + dfdga_phi_m, vbmu=0.0;              double dfdrb_phi_m, dfdgb_phi_m;              if (spin_polarized_) {                  dfdrb_phi_m = drhob*bs_values_[j];                  dfdgb_phi_m = gradsb[0]*bsg_values_[j*3+0] +                                       gradsb[1]*bsg_values_[j*3+1] +                                       gradsb[2]*bsg_values_[j*3+2];                  vbmu = dfdrb_phi_m + dfdgb_phi_m;                }              int jtoff = (jt*(jt+1))>>1;              for (int k=0; k <= j; k++) {                  int kt = contrib_bf_[k];                  int jtkt = jtoff + kt;                  double dfdga_phi_n = gradsa[0]*bsg_values_[k*3+0] +                                       gradsa[1]*bsg_values_[k*3+1] +                                       gradsa[2]*bsg_values_[k*3+2];                  alpha_vmat_[jtkt] += vamu * bs_values_[k] +                                     dfdga_phi_n * bs_values_[j];                  if (spin_polarized_) {                      double dfdgb_phi_n = gradsb[0]*bsg_values_[k*3+0] +                                           gradsb[1]*bsg_values_[k*3+1] +                                           gradsb[2]*bsg_values_[k*3+2];                      beta_vmat_[jtkt] += vbmu * bs_values_[k] +                                          dfdgb_phi_n * bs_values_[j];                    }                }            }        }      else {          double drhoa = w_mult*od.df_drho_a;          double drhob = w_mult*od.df_drho_b;          for (int j=0; j<ncontrib_bf_; j++) {              int jt = contrib_bf_[j];              double bsj = bs_values_[j];              double dfa_phi_m = drhoa * bsj;              double dfb_phi_m = drhob * bsj;              int jtoff = (jt*(jt+1))>>1;              for (int k=0; k <= j; k++) {                  int kt = contrib_bf_[k];                  int jtkt = jtoff + kt;                  double bsk = bs_values_[k];                  alpha_vmat_[jtkt] += dfa_phi_m * bsk;                  if (spin_polarized_)                      beta_vmat_[jtkt] += dfb_phi_m * bsk;                }            }        }    }  if (nuclear_gradient != 0) {      // the contribution from f dw/dx      if (w_gradient) {          for (i=0; i<natom_*3; i++) {              nuclear_gradient[i] += w_gradient[i] * od.energy * multiplier;            }        }      // the contribution from (df/dx) w      for (i=0; i<natom_*3; i++) {          nuclear_gradient[i] += f_gradient[i] * w_mult;        }    }  return id.a.rho + id.b.rho;}///////////////////////////////////////////////////////////////////////////// IntegrationWeightstatic ClassDesc IntegrationWeight_cd(  typeid(IntegrationWeight),"IntegrationWeight",1,"public SavableState",  0, 0, 0);IntegrationWeight::IntegrationWeight(StateIn& s):  SavableState(s){}IntegrationWeight::IntegrationWeight(){}IntegrationWeight::IntegrationWeight(const Ref<KeyVal>& keyval){}IntegrationWeight::~IntegrationWeight(){}voidIntegrationWeight::save_data_state(StateOut& s){}voidIntegrationWeight::init(const Ref<Molecule> &mol, double tolerance){  mol_ = mol;  tol_ = tolerance;}voidIntegrationWeight::done(){}voidIntegrationWeight::fd_w(int icenter, SCVector3 &point,                        double *fd_grad_w){  if (!fd_grad_w) return;  double delta = 0.001;  int natom = mol_->natom();  Ref<Molecule> molsav = mol_;  Ref<Molecule> dmol = new Molecule(*mol_.pointer());  for (int i=0; i<natom; i++) {      for (int j=0; j<3; j++) {          dmol->r(i,j) += delta;          if (icenter == i) point[j] += delta;          init(dmol,tol_);          double w_plus = w(icenter, point);          dmol->r(i,j) -= 2*delta;          if (icenter == i) point[j] -= 2*delta;          init(dmol,tol_);          double w_minus = w(icenter, point);          dmol->r(i,j) += delta;          if (icenter == i) point[j] += delta;          fd_grad_w[i*3+j] = (w_plus-w_minus)/(2.0*delta);//            ExEnv::outn() << scprintf("%d,%d %12.10f %12.10f %12.10f",//                             i,j,w_plus,w_minus,fd_grad_w[i*3+j])//                 << endl;        }    }  init(molsav, tol_);}voidIntegrationWeight::test(int icenter, SCVector3 &point){  int natom = mol_->natom();  int natom3 = natom*3;  // tests over sums of weights   int i;  double sum_weight = 0.0;  for (i=0; i<natom; i++) {      double weight = w(i,point);      sum_weight += weight;    }  if (fabs(1.0 - sum_weight) > DBL_EPSILON) {      ExEnv::out0() << "IntegrationWeight::test: failed on weight" << endl;      ExEnv::out0() << "sum_w = " << sum_weight << endl;    }  // finite displacement tests of weight gradients  double *fd_grad_w = new double[natom3];  double *an_grad_w = new double[natom3];  w(icenter, point, an_grad_w);  fd_w(icenter, point, fd_grad_w);  for (i=0; i<natom3; i++) {      double mag = fabs(fd_grad_w[i]);      double err = fabs(fd_grad_w[i]-an_grad_w[i]);      int bad = 0;      if (mag > 0.00001 && err/mag > 0.01) bad = 1;      else if (err > 0.00001) bad = 1;      if (bad) {          ExEnv::out0() << "iatom = " << i/3               << " ixyx = " << i%3               << " icenter = " << icenter << " point = " << point << endl;          ExEnv::out0() << scprintf("dw/dx bad: fd_val=%16.13f an_val=%16.13f err=%16.13f",                           fd_grad_w[i], an_grad_w[i],                           fd_grad_w[i]-an_grad_w[i])               << endl;        }    }  delete[] fd_grad_w;  delete[] an_grad_w;  }

⌨️ 快捷键说明

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