// // tcscf.cc --- implementation of the two-configuration SCF class // // Copyright (C) 1996 Limit Point Systems, Inc. // // Author: Edward Seidl // Maintainer: LPS // // This file is part of the SC Toolkit. // // The SC Toolkit is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // The SC Toolkit is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with the SC Toolkit; see the file COPYING.LIB. If not, write to // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // The U.S. Government is granted a limited license as per AL 91-7. // #ifdef __GNUC__ #pragma implementation #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace sc; /////////////////////////////////////////////////////////////////////////// // TCSCF static ClassDesc TCSCF_cd( typeid(TCSCF),"TCSCF",1,"public SCF", 0, 0, 0); TCSCF::TCSCF(StateIn& s) : SavableState(s), SCF(s), focka_(this), fockb_(this), ka_(this), kb_(this) { focka_.result_noupdate() = basis_matrixkit()->symmmatrix(so_dimension()); focka_.restore_state(s); focka_.result_noupdate().restore(s); fockb_.result_noupdate() = basis_matrixkit()->symmmatrix(so_dimension()); fockb_.restore_state(s); fockb_.result_noupdate().restore(s); ka_.result_noupdate() = basis_matrixkit()->symmmatrix(so_dimension()); ka_.restore_state(s); ka_.result_noupdate().restore(s); kb_.result_noupdate() = basis_matrixkit()->symmmatrix(so_dimension()); kb_.restore_state(s); kb_.result_noupdate().restore(s); s.get(user_occupations_); s.get(tndocc_); s.get(nirrep_); s.get(ndocc_); s.get(osa_); s.get(osb_); s.get(occa_); s.get(occb_); s.get(ci1_); s.get(ci2_); // now take care of memory stuff init_mem(8); } TCSCF::TCSCF(const Ref& keyval) : SCF(keyval), focka_(this), fockb_(this), ka_(this), kb_(this) { focka_.compute()=0; focka_.computed()=0; fockb_.compute()=0; fockb_.computed()=0; ka_.compute()=0; ka_.computed()=0; kb_.compute()=0; kb_.computed()=0; // calculate the total nuclear charge double Znuc=molecule()->nuclear_charge(); // check to see if this is to be a charged molecule double charge = keyval->doublevalue("total_charge"); int nelectrons = (int)(Znuc-charge+1.0e-4); // figure out how many doubly occupied shells there are if (keyval->exists("ndocc")) { tndocc_ = keyval->intvalue("ndocc"); } else { tndocc_ = (nelectrons-2)/2; if ((nelectrons-2)%2) { ExEnv::err0() << endl << indent << "TCSCF::init: Warning, there's a leftover electron.\n" << incindent << indent << "total_charge = " << charge << endl << indent << "total nuclear charge = " << Znuc << endl << indent << "ndocc_ = " << tndocc_ << endl << decindent; } } ExEnv::out0() << endl << indent << "TCSCF::init: total charge = " << Znuc-2*tndocc_-2 << endl << endl; nirrep_ = molecule()->point_group()->char_table().ncomp(); if (nirrep_==1) { ExEnv::err0() << indent << "TCSCF::init: cannot do C1 symmetry\n"; abort(); } occa_=occb_=1.0; ci1_=ci2_ = 0.5*sqrt(2.0); if (keyval->exists("ci1")) { ci1_ = keyval->doublevalue("ci1"); ci2_ = sqrt(1.0 - ci1_*ci1_); occa_ = 2.0*ci1_*ci1_; occb_ = 2.0*ci2_*ci2_; } if (keyval->exists("occa")) { occa_ = keyval->doublevalue("occa"); ci1_ = sqrt(occa_/2.0); ci2_ = sqrt(1.0 - ci1_*ci1_); occb_ = 2.0*ci2_*ci2_; } osa_=-1; osb_=-1; ndocc_ = read_occ(keyval, "docc", nirrep_); int *nsocc = read_occ(keyval, "socc", nirrep_); if (ndocc_ && nsocc) { user_occupations_=1; for (int i=0; i < nirrep_; i++) { int nsi = nsocc[i]; if (nsi && osa_<0) osa_=i; else if (nsi && osb_<0) osb_=i; else if (nsi) { ExEnv::err0() << indent << "TCSCF::init: too many open shells\n"; abort(); } } delete[] nsocc; } else if (ndocc_ && !nsocc || !ndocc_ && nsocc) { ExEnv::outn() << "ERROR: TCSCF: only one of docc and socc specified: " << "give both or none" << endl; abort(); } else { ndocc_=0; user_occupations_=0; set_occupations(0); } int i; ExEnv::out0() << indent << "docc = ["; for (i=0; i < nirrep_; i++) ExEnv::out0() << " " << ndocc_[i]; ExEnv::out0() << " ]\n"; ExEnv::out0() << indent << "socc = ["; for (i=0; i < nirrep_; i++) ExEnv::out0() << " " << (i==osa_ || i==osb_) ? 1 : 0; ExEnv::out0() << " ]\n"; // check to see if this was done in SCF(keyval) if (!keyval->exists("maxiter")) maxiter_ = 200; if (!keyval->exists("level_shift")) level_shift_ = 0.25; // now take care of memory stuff init_mem(8); } TCSCF::~TCSCF() { if (ndocc_) { delete[] ndocc_; ndocc_=0; } } void TCSCF::save_data_state(StateOut& s) { SCF::save_data_state(s); focka_.save_data_state(s); focka_.result_noupdate().save(s); fockb_.save_data_state(s); fockb_.result_noupdate().save(s); ka_.save_data_state(s); ka_.result_noupdate().save(s); kb_.save_data_state(s); kb_.result_noupdate().save(s); s.put(user_occupations_); s.put(tndocc_); s.put(nirrep_); s.put(ndocc_,nirrep_); s.put(osa_); s.put(osb_); s.put(occa_); s.put(occb_); s.put(ci1_); s.put(ci2_); } double TCSCF::occupation(int ir, int i) { if (i < ndocc_[ir]) return 2.0; else if (ir==osa_ && i==ndocc_[ir]) return occa_; else if (ir==osb_ && i==ndocc_[ir]) return occb_; else return 0.0; } double TCSCF::alpha_occupation(int ir, int i) { if (i < ndocc_[ir]) return 1.0; else if (ir==osa_ && i==ndocc_[ir]) return 0.5*occa_; return 0.0; } double TCSCF::beta_occupation(int ir, int i) { if (i < ndocc_[ir]) return 1.0; else if (ir==osb_ && i==ndocc_[ir]) return 0.5*occb_; return 0.0; } int TCSCF::n_fock_matrices() const { return 4; } RefSymmSCMatrix TCSCF::fock(int n) { if (n > 3) { ExEnv::err0() << indent << "TCSCF::fock: there are only four fock matrices, " << scprintf("but fock(%d) was requested\n", n); abort(); } if (n==0) return focka_.result(); else if (n==1) return fockb_.result(); else if (n==2) return ka_.result(); else return kb_.result(); } int TCSCF::spin_polarized() { return 1; } void TCSCF::print(ostream&o) const { int i; SCF::print(o); o << indent << "TCSCF Parameters:\n" << incindent << indent << "ndocc = " << tndocc_ << endl << indent << scprintf("occa = %f", occa_) << endl << indent << scprintf("occb = %f", occb_) << endl << indent << scprintf("ci1 = %9.6f", ci1_) << endl << indent << scprintf("ci2 = %9.6f", ci2_) << endl << indent << "docc = ["; for (i=0; i < nirrep_; i++) o << " " << ndocc_[i]; o << " ]" << endl << indent << "socc = ["; for (i=0; i < nirrep_; i++) o << " " << (i==osa_ || i==osb_) ? 1 : 0; o << " ]" << endl << decindent << endl; } ////////////////////////////////////////////////////////////////////////////// void TCSCF::set_occupations(const RefDiagSCMatrix& ev) { if (user_occupations_) return; int i,j; RefDiagSCMatrix evals; if (ev.null()) { initial_vector(0); evals = eigenvalues_.result_noupdate(); } else evals = ev; // first convert evals to something we can deal with easily BlockedDiagSCMatrix *evalsb = require_dynamic_cast(evals, "TCSCF::set_occupations"); double **vals = new double*[nirrep_]; for (i=0; i < nirrep_; i++) { int nf=oso_dimension()->blocks()->size(i); if (nf) { vals[i] = new double[nf]; evalsb->block(i)->convert(vals[i]); } else { vals[i] = 0; } } // now loop to find the tndocc_ lowest eigenvalues and populate those // MO's int *newdocc = new int[nirrep_]; memset(newdocc,0,sizeof(int)*nirrep_); for (i=0; i < tndocc_; i++) { // find lowest eigenvalue int lir=0,ln=0; double lowest=999999999; for (int ir=0; ir < nirrep_; ir++) { int nf=oso_dimension()->blocks()->size(ir); if (!nf) continue; for (j=0; j < nf; j++) { if (vals[ir][j] < lowest) { lowest=vals[ir][j]; lir=ir; ln=j; } } } vals[lir][ln]=999999999; newdocc[lir]++; } int osa=-1, osb=-1; for (i=0; i < 2; i++) { // find lowest eigenvalue int lir=0,ln=0; double lowest=999999999; for (int ir=0; ir < nirrep_; ir++) { int nf=oso_dimension()->blocks()->size(ir); if (!nf) continue; for (j=0; j < nf; j++) { if (vals[ir][j] < lowest) { lowest=vals[ir][j]; lir=ir; ln=j; } } } vals[lir][ln]=999999999; if (!i) { osa=lir; } else { if (lir==osa) { i--; continue; } osb=lir; } } if (osa > osb) { int tmp=osa; osa=osb; osb=tmp; } // get rid of vals for (i=0; i < nirrep_; i++) if (vals[i]) delete[] vals[i]; delete[] vals; if (!ndocc_) { ndocc_=newdocc; osa_=osa; osb_=osb; } else { // test to see if newocc is different from ndocc_ for (i=0; i < nirrep_; i++) { if (ndocc_[i] != newdocc[i]) { ExEnv::err0() << indent << "TCSCF::set_occupations: WARNING!!!!\n" << 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 (((osa != osa_ && osa != osb_) || (osb != osb_ && osb != osa_))) { ExEnv::err0() << indent << "TCSCF::set_occupations: WARNING!!!!\n" << incindent << indent << "open shell occupations have changed" << endl << decindent; osa_=osa; osb_=osb; reset_density(); } } memcpy(ndocc_,newdocc,sizeof(int)*nirrep_); delete[] newdocc; } } void TCSCF::symmetry_changed() { SCF::symmetry_changed(); focka_.result_noupdate()=0; fockb_.result_noupdate()=0; ka_.result_noupdate()=0; kb_.result_noupdate()=0; nirrep_ = molecule()->point_group()->char_table().ncomp(); set_occupations(0); } ////////////////////////////////////////////////////////////////////////////// // // scf things // void TCSCF::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_densa_ = hcore_.clone(); op_densa_.assign(0.0); op_densa_diff_ = hcore_.clone(); op_densa_diff_.assign(0.0); op_densb_ = hcore_.clone(); op_densb_.assign(0.0); op_densb_diff_ = hcore_.clone(); op_densb_diff_.assign(0.0); // gmat is in AO basis ao_gmata_ = basis()->matrixkit()->symmmatrix(basis()->basisdim()); ao_gmata_.assign(0.0); ao_gmatb_ = ao_gmata_.clone(); ao_gmatb_.assign(0.0); ao_ka_ = ao_gmata_.clone(); ao_ka_.assign(0.0); ao_kb_ = ao_gmata_.clone(); ao_kb_.assign(0.0); // test to see if we need a guess vector if (focka_.result_noupdate().null()) { focka_ = hcore_.clone(); focka_.result_noupdate().assign(0.0); fockb_ = hcore_.clone(); fockb_.result_noupdate().assign(0.0); ka_ = hcore_.clone(); ka_.result_noupdate().assign(0.0); kb_ = hcore_.clone(); kb_.result_noupdate().assign(0.0); } // set up trial vector initial_vector(1); oso_scf_vector_ = oso_eigenvectors_.result_noupdate(); } void TCSCF::done_vector() { done_threads(); cl_dens_ = 0; cl_dens_diff_ = 0; op_densa_ = 0; op_densa_diff_ = 0; op_densb_ = 0; op_densb_diff_ = 0; ao_gmata_ = 0; ao_gmatb_ = 0; ao_ka_ = 0; ao_kb_ = 0; oso_scf_vector_ = 0; } //////////////////////////////////////////////////////////////////////////// RefSymmSCMatrix TCSCF::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, occa_); dens1.scale(occa_); dens.accumulate(dens1); so_density(dens1, occb_); dens1.scale(occb_); 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(); } RefSymmSCMatrix TCSCF::alpha_density() { RefSymmSCMatrix dens(so_dimension(), basis_matrixkit()); RefSymmSCMatrix dens1(so_dimension(), basis_matrixkit()); so_density(dens, 2.0); so_density(dens1, occa_); dens.accumulate(dens1); dens.scale(2.0); return dens; } RefSymmSCMatrix TCSCF::beta_density() { RefSymmSCMatrix dens(so_dimension(), basis_matrixkit()); RefSymmSCMatrix dens1(so_dimension(), basis_matrixkit()); so_density(dens, 2.0); so_density(dens1, occb_); dens.accumulate(dens1); dens.scale(2.0); return dens; } void TCSCF::reset_density() { cl_dens_diff_.assign(cl_dens_); ao_gmata_.assign(0.0); op_densa_diff_.assign(op_densa_); ao_gmatb_.assign(0.0); op_densb_diff_.assign(op_densb_); ao_ka_.assign(0.0); ao_kb_.assign(0.0); } double TCSCF::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_densa_diff_.assign(op_densa_); op_densa_diff_.scale(-1.0); op_densb_diff_.assign(op_densb_); op_densb_diff_.scale(-1.0); so_density(cl_dens_, 2.0); cl_dens_.scale(2.0); so_density(op_densa_, occa_); dynamic_cast(op_densa_.pointer())->block(osb_)->assign(0.0); op_densa_.scale(2.0); so_density(op_densb_, occb_); dynamic_cast(op_densb_.pointer())->block(osa_)->assign(0.0); op_densb_.scale(2.0); cl_dens_diff_.accumulate(cl_dens_); op_densa_diff_.accumulate(op_densa_); op_densb_diff_.accumulate(op_densb_); RefSymmSCMatrix del = cl_dens_diff_.copy(); del.accumulate(op_densa_diff_); del.accumulate(op_densb_diff_); Ref sp(new SCElementScalarProduct); del.element_op(sp.pointer(), del); double delta = sp->result(); delta = sqrt(delta/i_offset(cl_dens_diff_.n())); return delta; } double TCSCF::scf_energy() { // first calculate the elements of the CI matrix SCFEnergy *eop = new SCFEnergy; eop->reference(); Ref op = eop; RefSymmSCMatrix t = focka_.result_noupdate().copy(); t.accumulate(hcore_); RefSymmSCMatrix d = cl_dens_.copy(); d.accumulate(op_densa_); t.element_op(op, d); double h11 = eop->result(); t.assign(fockb_.result_noupdate().copy()); t.accumulate(hcore_); d.assign(cl_dens_); d.accumulate(op_densb_); eop->reset(); t.element_op(op, d); double h22 = eop->result(); //t = ka_.result_noupdate(); //eop->reset(); //t.element_op(op, op_densb_); //double h21 = eop->result(); t = kb_.result_noupdate(); eop->reset(); t.element_op(op, op_densa_); double h12 = eop->result(); op=0; eop->dereference(); delete eop; // now diagonalize the CI matrix to get the coefficients RefSCDimension l2 = new SCDimension(2); Ref lkit = new LocalSCMatrixKit; RefSymmSCMatrix h = lkit->symmmatrix(l2); RefSCMatrix hv = lkit->matrix(l2,l2); RefDiagSCMatrix hl = lkit->diagmatrix(l2); h.set_element(0,0,h11); h.set_element(1,1,h22); h.set_element(1,0,h12); h.diagonalize(hl,hv); ci1_ = hv.get_element(0,0); ci2_ = hv.get_element(1,0); double c1c2 = ci1_*ci2_; ExEnv::out0() << indent << scprintf("c1 = %10.7f c2 = %10.7f", ci1_, ci2_) << endl; occa_ = 2*ci1_*ci1_; occb_ = 2*ci2_*ci2_; double eelec = 0.5*occa_*h11 + 0.5*occb_*h22 + 2.0*c1c2*h12; return eelec; } Ref TCSCF::extrap_data() { RefSymmSCMatrix *m = new RefSymmSCMatrix[4]; m[0] = focka_.result_noupdate(); m[1] = fockb_.result_noupdate(); m[2] = ka_.result_noupdate(); m[3] = kb_.result_noupdate(); Ref data = new SymmSCMatrixNSCExtrapData(4, m); delete[] m; return data; } RefSymmSCMatrix TCSCF::effective_fock() { // use fock() instead of cl_fock_ just in case this is called from // someplace outside SCF::compute_vector() RefSymmSCMatrix mofocka(oso_dimension(), basis_matrixkit()); mofocka.assign(0.0); RefSymmSCMatrix mofockb(oso_dimension(), basis_matrixkit()); mofockb.assign(0.0); RefSymmSCMatrix moka = mofocka.clone(); moka.assign(0.0); RefSymmSCMatrix mokb = mofocka.clone(); mokb.assign(0.0); // use eigenvectors if oso_scf_vector_ is null RefSCMatrix vec; if (oso_scf_vector_.null()) { vec = eigenvectors(); } else { vec = so_to_orthog_so().t() * oso_scf_vector_; } mofocka.accumulate_transform(vec, fock(0), SCMatrix::TransposeTransform); mofockb.accumulate_transform(vec, fock(1), SCMatrix::TransposeTransform); moka.accumulate_transform(vec, fock(2), SCMatrix::TransposeTransform); mokb.accumulate_transform(vec, fock(3), SCMatrix::TransposeTransform); mofocka.scale(ci1_*ci1_); mofockb.scale(ci2_*ci2_); moka.scale(ci1_*ci2_); mokb.scale(ci1_*ci2_); RefSymmSCMatrix mofock = mofocka.copy(); mofock.accumulate(mofockb); BlockedSymmSCMatrix *F = dynamic_cast(mofock.pointer()); BlockedSymmSCMatrix *Fa = dynamic_cast(mofocka.pointer()); BlockedSymmSCMatrix *Fb = dynamic_cast(mofockb.pointer()); BlockedSymmSCMatrix *Ka = dynamic_cast(moka.pointer()); BlockedSymmSCMatrix *Kb = dynamic_cast(mokb.pointer()); double scalea = (fabs(ci1_) < fabs(ci2_)) ? 1.0/(ci1_*ci1_ + 0.05) : 1.0; double scaleb = (fabs(ci2_) < fabs(ci1_)) ? 1.0/(ci2_*ci2_ + 0.05) : 1.0; for (int b=0; b < Fa->nblocks(); b++) { if (b==osa_) { RefSymmSCMatrix f = F->block(b); RefSymmSCMatrix fa = Fa->block(b); RefSymmSCMatrix fb = Fb->block(b); RefSymmSCMatrix kb = Kb->block(b); int i,j; i=ndocc_[b]; for (j=0; j < ndocc_[b]; j++) f->set_element(i,j, scaleb*(fb->get_element(i,j)-kb->get_element(i,j))); j=ndocc_[b]; for (i=ndocc_[b]+1; i < f->n(); i++) f->set_element(i,j, scalea*(fa->get_element(i,j)+kb->get_element(i,j))); } else if (b==osb_) { RefSymmSCMatrix f = F->block(b); RefSymmSCMatrix fa = Fa->block(b); RefSymmSCMatrix fb = Fb->block(b); RefSymmSCMatrix ka = Ka->block(b); int i,j; i=ndocc_[b]; for (j=0; j < ndocc_[b]; j++) f->set_element(i,j, scalea*(fa->get_element(i,j)-ka->get_element(i,j))); j=ndocc_[b]; for (i=ndocc_[b]+1; i < f->n(); i++) f->set_element(i,j, scaleb*(fb->get_element(i,j)+ka->get_element(i,j))); } } return mofock; } ///////////////////////////////////////////////////////////////////////////// void TCSCF::init_gradient() { // presumably the eigenvectors have already been computed by the time // we get here oso_scf_vector_ = oso_eigenvectors_.result_noupdate(); } void TCSCF::done_gradient() { cl_dens_=0; op_densa_=0; op_densb_=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| // RefSymmSCMatrix TCSCF::lagrangian() { RefSCMatrix vec = so_to_orthog_so().t() * oso_scf_vector_; RefSymmSCMatrix mofocka = focka_.result_noupdate().clone(); mofocka.assign(0.0); mofocka.accumulate_transform(vec, focka_.result_noupdate(), SCMatrix::TransposeTransform); mofocka.scale(ci1_*ci1_); RefSymmSCMatrix mofockb = mofocka.clone(); mofockb.assign(0.0); mofockb.accumulate_transform(vec, fockb_.result_noupdate(), SCMatrix::TransposeTransform); mofockb.scale(ci2_*ci2_); // FOa = c1^2*Fa + c1c2*Kb RefSymmSCMatrix moka = mofocka.clone(); moka.assign(0.0); moka.accumulate_transform(vec, kb_.result_noupdate(), SCMatrix::TransposeTransform); moka.scale(ci1_*ci2_); moka.accumulate(mofocka); // FOb = c1^2*Fb + c1c2*Ka RefSymmSCMatrix mokb = mofocka.clone(); mokb.assign(0.0); mokb.accumulate_transform(vec, ka_.result_noupdate(), SCMatrix::TransposeTransform); mokb.scale(ci1_*ci2_); mokb.accumulate(mofockb); dynamic_cast(moka.pointer())->block(osb_)->assign(0.0); dynamic_cast(mokb.pointer())->block(osa_)->assign(0.0); moka.accumulate(mokb); mokb=0; // FC = c1^2*Fa + c2^2*Fb mofocka.accumulate(mofockb); mofockb=0; Ref op = new MOLagrangian(this); mofocka.element_op(op, moka); moka=0; mofocka.scale(2.0); // transform MO lagrangian to SO basis RefSymmSCMatrix so_lag(so_dimension(), basis_matrixkit()); so_lag.assign(0.0); so_lag.accumulate_transform(vec, mofocka); // and then from SO to AO Ref pl = integral()->petite_list(); RefSymmSCMatrix ao_lag = pl->to_AO_basis(so_lag); ao_lag.scale(-1.0); return ao_lag; } RefSymmSCMatrix TCSCF::gradient_density() { cl_dens_ = basis_matrixkit()->symmmatrix(so_dimension()); op_densa_ = cl_dens_.clone(); op_densb_ = cl_dens_.clone(); so_density(cl_dens_, 2.0); cl_dens_.scale(2.0); so_density(op_densa_, occa_); op_densa_.scale(occa_); so_density(op_densb_, occb_); op_densb_.scale(occb_); dynamic_cast(op_densa_.pointer())->block(osb_)->assign(0.0); dynamic_cast(op_densb_.pointer())->block(osa_)->assign(0.0); Ref pl = integral()->petite_list(basis()); cl_dens_ = pl->to_AO_basis(cl_dens_); op_densa_ = pl->to_AO_basis(op_densa_); op_densb_ = pl->to_AO_basis(op_densb_); RefSymmSCMatrix tdens = cl_dens_.copy(); tdens.accumulate(op_densa_); tdens.accumulate(op_densb_); op_densa_.scale(2.0/occa_); op_densb_.scale(2.0/occb_); return tdens; } ///////////////////////////////////////////////////////////////////////////// void TCSCF::init_hessian() { } void TCSCF::done_hessian() { } ///////////////////////////////////////////////////////////////////////////// // Local Variables: // mode: c++ // c-file-style: "ETS" // End: