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 + -
显示快捷键?