class BlockedUnrestrictedSCF(SelfConsistentField):

    def __init__(self, linear_algebra, electrons, multiplicity, overlap, hamiltonian_matrix_factory):
        super().__init__(linear_algebra, electrons, hamiltonian_matrix_factory)
        self.electrons_alph = (electrons + multiplicity - 1) // 2
        self.electrons_beta = (electrons - multiplicity + 1) // 2
        self.diis = DIIS(overlap, linear_algebra)

    def begin_iterations(self, orbital_coefficients):
        orbital_energies = []
        total_energy = previous_total_energy = 0

        while True:

            if total_energy == 0:
                density_matrix = blocked_density_matrix(orbital_coefficients, orbital_coefficients.shape[0] // 2, 0)
            else:
                density_matrix = blocked_density_matrix(orbital_coefficients, self.electrons_alph, self.electrons_beta)

            fock_matrix = self.hamiltonian_matrix_factory.create(density_matrix)
            total_energy = self.calculate.restricted(density_matrix, fock_matrix)
            delta_energy = previous_total_energy - total_energy
            previous_total_energy = total_energy
            print('SCF ENERGY: ' + str(total_energy) + ' a.u.')

            if abs(delta_energy) < self.threshold:
                break

            fock_matrix = self.diis.fock_matrix(fock_matrix, density_matrix)
            orbital_energies, orbital_coefficients = self.linear_algebra.diagonalize(fock_matrix)

        return total_energy, orbital_energies, orbital_coefficients
class RestrictedSCF(SelfConsistentField):

    def __init__(self, linear_algebra, electrons, overlap, hamiltonian_matrix_factory):
        super().__init__(linear_algebra, electrons, hamiltonian_matrix_factory)
        self.diis = DIIS(overlap, linear_algebra)

    def begin_iterations(self, orbital_coefficients):
        orbital_energies = []
        total_energy = previous_total_energy = 0

        while True:

            density_matrix = density_matrix_restricted(orbital_coefficients, self.electrons)
            fock_matrix = self.hamiltonian_matrix_factory.create(density_matrix)
            total_energy = self.calculate.restricted(density_matrix, fock_matrix)
            delta_energy = previous_total_energy - total_energy
            previous_total_energy = total_energy
            print('SCF ENERGY: ' + str(total_energy) + ' a.u.')

            if abs(delta_energy) < self.threshold:
                break

            fock_matrix = self.diis.fock_matrix(fock_matrix, density_matrix)
            orbital_energies, orbital_coefficients = self.linear_algebra.diagonalize(fock_matrix)

        return total_energy, orbital_energies, orbital_coefficients
 def __init__(self, linear_algebra, electrons, multiplicity, overlap, hamiltonian_matrix_factory):
     super().__init__(linear_algebra, electrons, hamiltonian_matrix_factory)
     self.electrons_alph = (electrons + multiplicity - 1) // 2
     self.electrons_beta = (electrons - multiplicity + 1) // 2
     self.diis = DIIS(overlap, linear_algebra)
 def __init__(self, linear_algebra, electrons, overlap, hamiltonian_matrix_factory):
     super().__init__(linear_algebra, electrons, hamiltonian_matrix_factory)
     self.diis = DIIS(overlap, linear_algebra)