C_right_ and C_left_ at jk calculation

I was following SCF iteration source code (scf_iterator.py rhf.cc and jk.cc) then I confused how C_right_ = C_left_ are computed also i couldn’t find definition of C_left()

void RHF::form_G() {
if (functional_->needs_xc()) {
form_V();
G_->copy(Va_);
} else {
G_->zero();
}

/// Push the C matrix on
std::vector<SharedMatrix>& C = jk_->C_left();
C.clear();
C.push_back(Ca_subset("SO", "OCC"));

// Run the JK object
jk_->compute();

and

void JK::compute() {
// Is this density symmetric?
if (C_left_.size() && !C_right_.size()) {
lr_symmetric_ = true;
C_right_ = C_left_;
} else {
lr_symmetric_ = false;
}

Interested in knowing how it get the density every time it calculates jk?

The density can be constructed from the (occupied block of) the C matrices, which are accessed by the Ca_subset function and put onto C_left in exactly the lines of code you quoted. It is more efficient not to use the density directly, but to decompose the density into the product of C matrices.

If that doesn’t answer the question, I’ll need you to explain more precisely.

1 Like

thanks Dear Jonathon.
for me the important thing is to know what density that jk module depends on to compute J K and wK (physical importance), because if I am not mistaken, when I followed the code lines in chronological order, variable (C_right_ = C_left_) appeared to me and I did not see that they were calculated before.

another thing , if I am not mistaken, effective fragment potential contribution energy was computed twice. once when add to H_ , prior SCF iteration loop (the another addition at final) :

            Vefp = modify_Fock_permanent(self.molecule(), mints, verbose=verbose - 1)
            Vefp = core.Matrix.from_array(Vefp)
            self.H().add(Vefp)

during iteration loop:

            Vefp = modify_Fock_induced(self.molecule().EFP, mints_psi4_yo, verbose=verbose - 1)
            Vefp = core.Matrix.from_array(Vefp)
            self.H().add(Vefp)

so when compute one electron energy uefp is also computed:

double RHF::compute_E() {
    double one_electron_E = 2.0 * Da_->vector_dot(H_);

After, set energy of efp as “EFP”:

        efpobj.compute()  # do_gradient=do_gradient)
        efpene = efpobj.get_energy(label='psi')
        efp_wfn_independent_energy = efpene['total'] - efpene['ind']
        self.set_energies("EFP", efpene['total'])

however, at the final stages, efp contribution doubly computed by add one electron E and e efp:

    enuc = self.get_energies('Nuclear')
    e1 = self.get_energies('One-Electron')
    e2 = self.get_energies('Two-Electron')
    exc = self.get_energies('XC')
    ed = self.get_energies('-D')
    self.del_variable('-D Energy')
    evv10 = self.get_energies('VV10')
    eefp = self.get_energies('EFP')
    epcm = self.get_energies('PCM Polarization')
    edd = self.get_energies('DD Solvation Energy')
    epe = self.get_energies('PE Energy')
    ke = self.get_energies('Kinetic')

    hf_energy = enuc + e1 + e2
    dft_energy = hf_energy + exc + ed + evv10
    total_energy = dft_energy + eefp + epcm + edd + epe

Can someone clarify if the energy contribution of EFP is counted twice?

Do not add new, unrelated questions to an existing topic. Ask a new question instead.

JK::compute assumes that C_left_ is already populated. Some other method is responsible for that. In SCF, this happens in the code you’ve already posted. C.push_back(Ca_subset("SO", "OCC"));. It uses the current occupied orbitals.