hsosscf.cc

来自「大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CH」· CC 代码 · 共 874 行 · 第 1/2 页

CC
874
字号
             << incindent << indent             << scprintf("occupations for irrep %d have changed\n",i+1)             << indent             << scprintf("ndocc was %d, changed to %d", ndocc_[i], newdocc[i])             << endl << decindent;      }      if (nsocc_[i] != newsocc[i]) {        ExEnv::err0() << indent << "HSOSSCF::set_occupations:  WARNING!!!!\n"             << incindent << indent             << scprintf("occupations for irrep %d have changed\n",i+1)             << indent             << scprintf("nsocc was %d, changed to %d", nsocc_[i], newsocc[i])             << endl << decindent;      }    }    memcpy(ndocc_,newdocc,sizeof(int)*nirrep_);    memcpy(nsocc_,newsocc,sizeof(int)*nirrep_);    delete[] newdocc;    delete[] newsocc;  }  if (!initial_ndocc_      || initial_pg_->equiv(molecule()->point_group())) {    delete[] initial_ndocc_;    initial_ndocc_ = new int[nirrep_];    memcpy(initial_ndocc_,ndocc_,sizeof(int)*nirrep_);  }  if (!initial_nsocc_      || initial_pg_->equiv(molecule()->point_group())) {    delete[] initial_nsocc_;    initial_nsocc_ = new int[nirrep_];    memcpy(initial_nsocc_,nsocc_,sizeof(int)*nirrep_);  }  most_recent_pg_ = new PointGroup(molecule()->point_group());}voidHSOSSCF::symmetry_changed(){  SCF::symmetry_changed();  cl_fock_.result_noupdate()=0;  op_fock_.result_noupdate()=0;  nirrep_ = molecule()->point_group()->char_table().ncomp();  set_occupations(0);}////////////////////////////////////////////////////////////////////////////////// scf things//voidHSOSSCF::init_vector(){  init_threads();  // allocate storage for other temp matrices  cl_dens_ = hcore_.clone();  cl_dens_.assign(0.0);    cl_dens_diff_ = hcore_.clone();  cl_dens_diff_.assign(0.0);  op_dens_ = hcore_.clone();  op_dens_.assign(0.0);    op_dens_diff_ = hcore_.clone();  op_dens_diff_.assign(0.0);  // gmat is in AO basis  cl_gmat_ = basis()->matrixkit()->symmmatrix(basis()->basisdim());  cl_gmat_.assign(0.0);  op_gmat_ = cl_gmat_.clone();  op_gmat_.assign(0.0);  if (cl_fock_.result_noupdate().null()) {    cl_fock_ = hcore_.clone();    cl_fock_.result_noupdate().assign(0.0);    op_fock_ = hcore_.clone();    op_fock_.result_noupdate().assign(0.0);  }  // set up trial vector  initial_vector(1);      oso_scf_vector_ = oso_eigenvectors_.result_noupdate();}voidHSOSSCF::done_vector(){  done_threads();  cl_gmat_ = 0;  cl_dens_ = 0;  cl_dens_diff_ = 0;  op_gmat_ = 0;  op_dens_ = 0;  op_dens_diff_ = 0;  oso_scf_vector_ = 0;}RefSymmSCMatrixHSOSSCF::alpha_density(){  RefSymmSCMatrix dens1(so_dimension(), basis_matrixkit());  RefSymmSCMatrix dens2(so_dimension(), basis_matrixkit());  so_density(dens1, 2.0);  so_density(dens2, 1.0);  dens1.accumulate(dens2);  dens2=0;  return dens1;}RefSymmSCMatrixHSOSSCF::beta_density(){  RefSymmSCMatrix dens(so_dimension(), basis_matrixkit());  so_density(dens, 2.0);  return dens;}voidHSOSSCF::reset_density(){  cl_gmat_.assign(0.0);  cl_dens_diff_.assign(cl_dens_);  op_gmat_.assign(0.0);  op_dens_diff_.assign(op_dens_);}doubleHSOSSCF::new_density(){  // copy current density into density diff and scale by -1.  later we'll  // add the new density to this to get the density difference.  cl_dens_diff_.assign(cl_dens_);  cl_dens_diff_.scale(-1.0);  op_dens_diff_.assign(op_dens_);  op_dens_diff_.scale(-1.0);  so_density(cl_dens_, 2.0);  cl_dens_.scale(2.0);  so_density(op_dens_, 1.0);  cl_dens_.accumulate(op_dens_);    cl_dens_diff_.accumulate(cl_dens_);  op_dens_diff_.accumulate(op_dens_);  Ref<SCElementScalarProduct> sp(new SCElementScalarProduct);  cl_dens_diff_.element_op(sp.pointer(), cl_dens_diff_);    double delta = sp->result();  delta = sqrt(delta/i_offset(cl_dens_diff_.n()));  return delta;}RefSymmSCMatrixHSOSSCF::density(){  if (!density_.computed()) {    RefSymmSCMatrix dens(so_dimension(), basis_matrixkit());    RefSymmSCMatrix dens1(so_dimension(), basis_matrixkit());    so_density(dens, 2.0);    dens.scale(2.0);    so_density(dens1, 1.0);    dens.accumulate(dens1);    dens1=0;        density_ = dens;    // only flag the density as computed if the calc is converged    if (!value_needed()) density_.computed() = 1;  }  return density_.result_noupdate();}doubleHSOSSCF::scf_energy(){  RefSymmSCMatrix t = cl_fock_.result_noupdate().copy();  t.accumulate(hcore_);  RefSymmSCMatrix go = op_fock_.result_noupdate().copy();  go.scale(-1.0);  go.accumulate(cl_fock_.result_noupdate());    SCFEnergy *eop = new SCFEnergy;  eop->reference();  Ref<SCElementOp2> op = eop;  t.element_op(op, cl_dens_);  double cl_e = eop->result();    eop->reset();  go.element_op(op, op_dens_);  double op_e = eop->result();  op=0;  eop->dereference();  delete eop;  return cl_e-op_e;}Ref<SCExtrapData>HSOSSCF::extrap_data(){  Ref<SCExtrapData> data =    new SymmSCMatrix2SCExtrapData(cl_fock_.result_noupdate(),                                  op_fock_.result_noupdate());  return data;}RefSymmSCMatrixHSOSSCF::effective_fock(){  // use fock() instead of cl_fock_ just in case this is called from  // someplace outside SCF::compute_vector()  RefSymmSCMatrix mofock(oso_dimension(), basis_matrixkit());  mofock.assign(0.0);  RefSymmSCMatrix mofocko(oso_dimension(), basis_matrixkit());  mofocko.assign(0.0);  // use eigenvectors if oso_scf_vector_ is null  if (oso_scf_vector_.null()) {    mofock.accumulate_transform(eigenvectors(), fock(0),                                SCMatrix::TransposeTransform);    mofocko.accumulate_transform(eigenvectors(), fock(1),                                 SCMatrix::TransposeTransform);  } else {    RefSCMatrix so_to_oso_tr = so_to_orthog_so().t();    mofock.accumulate_transform(so_to_oso_tr * oso_scf_vector_, fock(0),                                SCMatrix::TransposeTransform);    mofocko.accumulate_transform(so_to_oso_tr * oso_scf_vector_, fock(1),                                 SCMatrix::TransposeTransform);  }  Ref<SCElementOp2> op = new GSGeneralEffH(this);  mofock.element_op(op, mofocko);  return mofock;}/////////////////////////////////////////////////////////////////////////////voidHSOSSCF::init_gradient(){  // presumably the eigenvectors have already been computed by the time  // we get here  oso_scf_vector_ = oso_eigenvectors_.result_noupdate();}voidHSOSSCF::done_gradient(){  cl_dens_=0;  op_dens_=0;  oso_scf_vector_ = 0;}/////////////////////////////////////////////////////////////////////////////// MO lagrangian//       c    o   v//  c  |2*FC|2*FC|0|//     -------------//  o  |2*FC| FO |0|//     -------------//  v  | 0  |  0 |0|//RefSymmSCMatrixHSOSSCF::lagrangian(){  RefSCMatrix so_to_oso_tr = so_to_orthog_so().t();  RefSymmSCMatrix mofock(oso_dimension(), basis_matrixkit());  mofock.assign(0.0);  mofock.accumulate_transform(so_to_oso_tr * oso_scf_vector_,                              cl_fock_.result_noupdate(),                              SCMatrix::TransposeTransform);  RefSymmSCMatrix mofocko(oso_dimension(), basis_matrixkit());  mofocko.assign(0.0);  mofocko.accumulate_transform(so_to_oso_tr * oso_scf_vector_,                               op_fock_.result_noupdate(),                               SCMatrix::TransposeTransform);  mofock.scale(2.0);    Ref<SCElementOp2> op = new MOLagrangian(this);  mofock.element_op(op, mofocko);  mofocko=0;  // transform MO lagrangian to SO basis  RefSymmSCMatrix so_lag(so_dimension(), basis_matrixkit());  so_lag.assign(0.0);  so_lag.accumulate_transform(so_to_oso_tr * oso_scf_vector_, mofock);    // and then from SO to AO  Ref<PetiteList> pl = integral()->petite_list();  RefSymmSCMatrix ao_lag = pl->to_AO_basis(so_lag);  ao_lag.scale(-1.0);  return ao_lag;}RefSymmSCMatrixHSOSSCF::gradient_density(){  cl_dens_ = basis_matrixkit()->symmmatrix(so_dimension());  op_dens_ = cl_dens_.clone();    so_density(cl_dens_, 2.0);  cl_dens_.scale(2.0);    so_density(op_dens_, 1.0);    Ref<PetiteList> pl = integral()->petite_list(basis());    cl_dens_ = pl->to_AO_basis(cl_dens_);  op_dens_ = pl->to_AO_basis(op_dens_);  RefSymmSCMatrix tdens = cl_dens_.copy();  tdens.accumulate(op_dens_);  op_dens_.scale(2.0);    return tdens;}/////////////////////////////////////////////////////////////////////////////voidHSOSSCF::init_hessian(){}voidHSOSSCF::done_hessian(){}/////////////////////////////////////////////////////////////////////////////voidHSOSSCF::two_body_deriv_hf(double * tbgrad, double exchange_fraction){  Ref<SCElementMaxAbs> m = new SCElementMaxAbs;  cl_dens_.element_op(m.pointer());  op_dens_.element_op(m.pointer());  double pmax = m->result();  m=0;  // now try to figure out the matrix specialization we're dealing with.  // if we're using Local matrices, then there's just one subblock, or  // see if we can convert P to local matrices  if (local_ || local_dens_) {    // grab the data pointers from the P matrices    double *pmat, *pmato;    RefSymmSCMatrix ptmp = get_local_data(cl_dens_, pmat, SCF::Read);    RefSymmSCMatrix potmp = get_local_data(op_dens_, pmato, SCF::Read);      Ref<PetiteList> pl = integral()->petite_list();    LocalHSOSGradContribution l(pmat,pmato);        int i;    int na3 = molecule()->natom()*3;    int nthread = threadgrp_->nthread();    double **grads = new double*[nthread];    Ref<TwoBodyDerivInt> *tbis = new Ref<TwoBodyDerivInt>[nthread];    for (i=0; i < nthread; i++) {       tbis[i] = integral()->electron_repulsion_deriv();      grads[i] = new double[na3];      memset(grads[i], 0, sizeof(double)*na3);    }    LocalTBGrad<LocalHSOSGradContribution> **tblds =      new LocalTBGrad<LocalHSOSGradContribution>*[nthread];    for (i=0; i < nthread; i++) {      tblds[i] = new LocalTBGrad<LocalHSOSGradContribution>(        l, tbis[i], pl, basis(), scf_grp_, grads[i], pmax,        desired_gradient_accuracy(), nthread, i, exchange_fraction);      threadgrp_->add_thread(i, tblds[i]);    }    if (threadgrp_->start_threads() < 0        ||threadgrp_->wait_threads() < 0) {      ExEnv::err0() << indent           << "HSOSSCF: error running threads" << endl;      abort();    }    for (i=0; i < nthread; i++) {      for (int j=0; j < na3; j++)        tbgrad[j] += grads[i][j];      delete[] grads[i];      delete tblds[i];    }    scf_grp_->sum(tbgrad, na3);  }  // for now quit  else {    ExEnv::err0() << indent         << "HSOSSCF::two_body_deriv: can't do gradient yet\n";    abort();  }}/////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "ETS"// End:

⌨️ 快捷键说明

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