parameters: (self)
return_statement: return energy
docstring: Performs stability analysis and calls back SCF with new guess
      if needed, Returns the SCF energy. This function should be called
      once orbitals are ready for energy/property computations, usually
      after iterations() is called.
docstring_summary: Performs stability analysis and calls back SCF with new guess
      if needed, Returns the SCF energy. This function should be called
      once orbitals are ready for energy/property computations, usually
      after iterations() is called.
docstring_tokens: Performs stability analysis and calls back SCF with new guess if needed Returns the SCF energy . This function should be called once orbitals are ready for energy / property computations usually after iterations () is called .
function: def scf_finalize_energy(self):
      """Performs stability analysis and calls back SCF with new guess
      if needed, Returns the SCF energy. This function should be called
      once orbitals are ready for energy/property computations, usually
      after iterations() is called.
  
      """
  
      # post-scf vv10 correlation
      if core.get_option('SCF', "DFT_VV10_POSTSCF") and self.functional().vv10_b() > 0.0:
          self.functional().set_lock(False)
          self.functional().set_do_vv10(True)
          self.functional().set_lock(True)
          core.print_out("  ==> Computing Non-Self-Consistent VV10 Energy Correction <==\n\n")
          SCFE = 0.0
          self.form_V()
          SCFE += self.compute_E()
          self.set_energies("Total Energy", SCFE)
  
      # Perform wavefunction stability analysis before doing
      # anything on a wavefunction that may not be truly converged.
      if core.get_option('SCF', 'STABILITY_ANALYSIS') != "NONE":
  
          # Don't bother computing needed integrals if we can't do anything with them.
          if self.functional().needs_xc():
              raise ValidationError("Stability analysis not yet supported for XC functionals.")
  
          # We need the integral file, make sure it is written and
          # compute it if needed
          if core.get_option('SCF', 'REFERENCE') != "UHF":
              #psio = core.IO.shared_object()
              #psio.open(constants.PSIF_SO_TEI, 1)  # PSIO_OPEN_OLD
              #try:
              #    psio.tocscan(constants.PSIF_SO_TEI, "IWL Buffers")
              #except TypeError:
              #    # "IWL Buffers" actually found but psio_tocentry can't be returned to Py
              #    psio.close(constants.PSIF_SO_TEI, 1)
              #else:
              #    # tocscan returned None
              #    psio.close(constants.PSIF_SO_TEI, 1)
  
              # logic above foiled by psio_tocentry not returning None<--nullptr in pb11 2.2.1
              #   so forcibly recomputing for now until stability revamp
              core.print_out("    SO Integrals not on disk. Computing...")
              mints = core.MintsHelper(self.basisset())
              #next 2 lines fix a bug that prohibits relativistic stability analysis
  
              mints.integrals()
              core.print_out("done.\n")
  
              # Q: Not worth exporting all the layers of psio, right?
  
          follow = self.stability_analysis()
  
          while follow and self.attempt_number_ <= core.get_option('SCF', 'MAX_ATTEMPTS'):
              self.attempt_number_ += 1
              core.print_out("    Running SCF again with the rotated orbitals.\n")
  
              if self.initialized_diis_manager_:
                  self.diis_manager_.reset_subspace()
              # reading the rotated orbitals in before starting iterations
              self.form_D()
              self.set_energies("Total Energy", self.compute_initial_E())
              self.iterations()
              follow = self.stability_analysis()
  
          if follow and self.attempt_number_ > core.get_option('SCF', 'MAX_ATTEMPTS'):
              core.print_out("    There's still a negative eigenvalue. Try modifying FOLLOW_STEP_SCALE\n")
              core.print_out("    or increasing MAX_ATTEMPTS (not available for PK integrals).\n")
  
      # At this point, we are not doing any more SCF cycles
      #   and we can compute and print final quantities.
  
      if hasattr(self.molecule(), 'EFP'):
          efpobj = self.molecule().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'])
  
          SCFE = self.get_energies("Total Energy")
          SCFE += efp_wfn_independent_energy
          self.set_energies("Total Energy", SCFE)
          core.print_out(efpobj.energy_summary(scfefp=SCFE, label='psi'))
  
          self.set_variable("EFP ELST ENERGY", efpene['electrostatic'] + efpene['charge_penetration'] + efpene['electrostatic_point_charges'])  # P::e EFP
          self.set_variable("EFP IND ENERGY", efpene['polarization'])  # P::e EFP
          self.set_variable("EFP DISP ENERGY", efpene['dispersion'])  # P::e EFP
          self.set_variable("EFP EXCH ENERGY", efpene['exchange_repulsion'])  # P::e EFP
          self.set_variable("EFP TOTAL ENERGY", efpene['total'])  # P::e EFP
          self.set_variable("CURRENT ENERGY", efpene['total'])  # P::e EFP
  
      core.print_out("\n  ==> Post-Iterations <==\n\n")
  
      if self.V_potential():
          quad = self.V_potential().quadrature_values()
          rho_a = quad['RHO_A']/2 if self.same_a_b_dens() else quad['RHO_A']
          rho_b = quad['RHO_B']/2 if self.same_a_b_dens() else quad['RHO_B']
          rho_ab = (rho_a + rho_b)
          self.set_variable("GRID ELECTRONS TOTAL",rho_ab)  # P::e SCF
          self.set_variable("GRID ELECTRONS ALPHA",rho_a)  # P::e SCF
          self.set_variable("GRID ELECTRONS BETA",rho_b)  # P::e SCF
          dev_a = rho_a - self.nalpha()
          dev_b = rho_b - self.nbeta()
          core.print_out(f"   Electrons on quadrature grid:\n")
          if self.same_a_b_dens():
              core.print_out(f"      Ntotal   = {rho_ab:15.10f} ; deviation = {dev_b+dev_a:.3e} \n\n")
          else:
              core.print_out(f"      Nalpha   = {rho_a:15.10f} ; deviation = {dev_a:.3e}\n")
              core.print_out(f"      Nbeta    = {rho_b:15.10f} ; deviation = {dev_b:.3e}\n")
              core.print_out(f"      Ntotal   = {rho_ab:15.10f} ; deviation = {dev_b+dev_a:.3e} \n\n")
          if ((dev_b+dev_a) > 0.1):
              core.print_out("   WARNING: large deviation in the electron count on grid detected. Check grid size!")
      self.check_phases()
      self.compute_spin_contamination()
      self.frac_renormalize()
      reference = core.get_option("SCF", "REFERENCE")
  
      energy = self.get_energies("Total Energy")
  
      #    fail_on_maxiter = core.get_option("SCF", "FAIL_ON_MAXITER")
      #    if converged or not fail_on_maxiter:
      #
      #        if print_lvl > 0:
      #            self.print_orbitals()
      #
      #        if converged:
      #            core.print_out("  Energy converged.\n\n")
      #        else:
      #            core.print_out("  Energy did not converge, but proceeding anyway.\n\n")
  
      if core.get_option('SCF', 'PRINT') > 0:
          self.print_orbitals()
  
      is_dfjk = core.get_global_option('SCF_TYPE').endswith('DF')
      core.print_out("  @%s%s Final Energy: %20.14f" % ('DF-' if is_dfjk else '', reference, energy))
      # if (perturb_h_) {
      #     core.print_out(" with %f %f %f perturbation" %
      #                    (dipole_field_strength_[0], dipole_field_strength_[1], dipole_field_strength_[2]))
      # }
      core.print_out("\n\n")
      self.print_energies()
  
      self.clear_external_potentials()
      if core.get_option('SCF', 'PCM'):
          calc_type = core.PCM.CalcType.Total
          if core.get_option("PCM", "PCM_SCF_TYPE") == "SEPARATE":
              calc_type = core.PCM.CalcType.NucAndEle
          Dt = self.Da().clone()
          Dt.add(self.Db())
          _, Vpcm = self.get_PCM().compute_PCM_terms(Dt, calc_type)
          self.push_back_external_potential(Vpcm)
          # Set callback function for CPSCF
          self.set_external_cpscf_perturbation("PCM", lambda pert_dm : self.get_PCM().compute_V(pert_dm))
  
      if core.get_option('SCF', 'PE'):
          Dt = self.Da().clone()
          Dt.add(self.Db())
          _, Vpe = self.pe_state.get_pe_contribution(
              Dt, elec_only=False
          )
          self.push_back_external_potential(Vpe)
          # Set callback function for CPSCF
          self.set_external_cpscf_perturbation("PE", lambda pert_dm : self.pe_state.get_pe_contribution(pert_dm, elec_only=True)[1])
  
      # Properties
      #  Comments so that autodoc utility will find these PSI variables
      #  Process::environment.globals["SCF DIPOLE X"] =
      #  Process::environment.globals["SCF DIPOLE Y"] =
      #  Process::environment.globals["SCF DIPOLE Z"] =
      #  Process::environment.globals["SCF QUADRUPOLE XX"] =
      #  Process::environment.globals["SCF QUADRUPOLE XY"] =
      #  Process::environment.globals["SCF QUADRUPOLE XZ"] =
      #  Process::environment.globals["SCF QUADRUPOLE YY"] =
      #  Process::environment.globals["SCF QUADRUPOLE YZ"] =
      #  Process::environment.globals["SCF QUADRUPOLE ZZ"] =
  
      # Orbitals are always saved, in case an MO guess is requested later
      # save_orbitals()
  
      # Shove variables into global space
      for k, v in self.variables().items():
          core.set_variable(k, v)
  
      # TODO re-enable
      self.finalize()
      if self.V_potential():
          self.V_potential().clear_collocation_cache()
  
      core.print_out("\nComputation Completed\n")
      core.del_variable("SCF D NORM")
  
      return energy
function_tokens: def scf_finalize_energy ( self ) : # post-scf vv10 correlation if core . get_option ( 'SCF' , "DFT_VV10_POSTSCF" ) and self . functional ( ) . vv10_b ( ) > 0.0 : self . functional ( ) . set_lock ( False ) self . functional ( ) . set_do_vv10 ( True ) self . functional ( ) . set_lock ( True ) core . print_out ( "  ==> Computing Non-Self-Consistent VV10 Energy Correction <==\n\n" ) SCFE = 0.0 self . form_V ( ) SCFE += self . compute_E ( ) self . set_energies ( "Total Energy" , SCFE ) # Perform wavefunction stability analysis before doing # anything on a wavefunction that may not be truly converged. if core . get_option ( 'SCF' , 'STABILITY_ANALYSIS' ) != "NONE" : # Don't bother computing needed integrals if we can't do anything with them. if self . functional ( ) . needs_xc ( ) : raise ValidationError ( "Stability analysis not yet supported for XC functionals." ) # We need the integral file, make sure it is written and # compute it if needed if core . get_option ( 'SCF' , 'REFERENCE' ) != "UHF" : #psio = core.IO.shared_object() #psio.open(constants.PSIF_SO_TEI, 1)  # PSIO_OPEN_OLD #try: #    psio.tocscan(constants.PSIF_SO_TEI, "IWL Buffers") #except TypeError: #    # "IWL Buffers" actually found but psio_tocentry can't be returned to Py #    psio.close(constants.PSIF_SO_TEI, 1) #else: #    # tocscan returned None #    psio.close(constants.PSIF_SO_TEI, 1) # logic above foiled by psio_tocentry not returning None<--nullptr in pb11 2.2.1 #   so forcibly recomputing for now until stability revamp core . print_out ( "    SO Integrals not on disk. Computing..." ) mints = core . MintsHelper ( self . basisset ( ) ) #next 2 lines fix a bug that prohibits relativistic stability analysis mints . integrals ( ) core . print_out ( "done.\n" ) # Q: Not worth exporting all the layers of psio, right? follow = self . stability_analysis ( ) while follow and self . attempt_number_ <= core . get_option ( 'SCF' , 'MAX_ATTEMPTS' ) : self . attempt_number_ += 1 core . print_out ( "    Running SCF again with the rotated orbitals.\n" ) if self . initialized_diis_manager_ : self . diis_manager_ . reset_subspace ( ) # reading the rotated orbitals in before starting iterations self . form_D ( ) self . set_energies ( "Total Energy" , self . compute_initial_E ( ) ) self . iterations ( ) follow = self . stability_analysis ( ) if follow and self . attempt_number_ > core . get_option ( 'SCF' , 'MAX_ATTEMPTS' ) : core . print_out ( "    There's still a negative eigenvalue. Try modifying FOLLOW_STEP_SCALE\n" ) core . print_out ( "    or increasing MAX_ATTEMPTS (not available for PK integrals).\n" ) # At this point, we are not doing any more SCF cycles #   and we can compute and print final quantities. if hasattr ( self . molecule ( ) , 'EFP' ) : efpobj = self . molecule ( ) . 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' ] ) SCFE = self . get_energies ( "Total Energy" ) SCFE += efp_wfn_independent_energy self . set_energies ( "Total Energy" , SCFE ) core . print_out ( efpobj . energy_summary ( scfefp = SCFE , label = 'psi' ) ) self . set_variable ( "EFP ELST ENERGY" , efpene [ 'electrostatic' ] + efpene [ 'charge_penetration' ] + efpene [ 'electrostatic_point_charges' ] ) # P::e EFP self . set_variable ( "EFP IND ENERGY" , efpene [ 'polarization' ] ) # P::e EFP self . set_variable ( "EFP DISP ENERGY" , efpene [ 'dispersion' ] ) # P::e EFP self . set_variable ( "EFP EXCH ENERGY" , efpene [ 'exchange_repulsion' ] ) # P::e EFP self . set_variable ( "EFP TOTAL ENERGY" , efpene [ 'total' ] ) # P::e EFP self . set_variable ( "CURRENT ENERGY" , efpene [ 'total' ] ) # P::e EFP core . print_out ( "\n  ==> Post-Iterations <==\n\n" ) if self . V_potential ( ) : quad = self . V_potential ( ) . quadrature_values ( ) rho_a = quad [ 'RHO_A' ] / 2 if self . same_a_b_dens ( ) else quad [ 'RHO_A' ] rho_b = quad [ 'RHO_B' ] / 2 if self . same_a_b_dens ( ) else quad [ 'RHO_B' ] rho_ab = ( rho_a + rho_b ) self . set_variable ( "GRID ELECTRONS TOTAL" , rho_ab ) # P::e SCF self . set_variable ( "GRID ELECTRONS ALPHA" , rho_a ) # P::e SCF self . set_variable ( "GRID ELECTRONS BETA" , rho_b ) # P::e SCF dev_a = rho_a - self . nalpha ( ) dev_b = rho_b - self . nbeta ( ) core . print_out ( f"   Electrons on quadrature grid:\n" ) if self . same_a_b_dens ( ) : core . print_out ( f"      Ntotal   = {rho_ab:15.10f} ; deviation = {dev_b+dev_a:.3e} \n\n" ) else : core . print_out ( f"      Nalpha   = {rho_a:15.10f} ; deviation = {dev_a:.3e}\n" ) core . print_out ( f"      Nbeta    = {rho_b:15.10f} ; deviation = {dev_b:.3e}\n" ) core . print_out ( f"      Ntotal   = {rho_ab:15.10f} ; deviation = {dev_b+dev_a:.3e} \n\n" ) if ( ( dev_b + dev_a ) > 0.1 ) : core . print_out ( "   WARNING: large deviation in the electron count on grid detected. Check grid size!" ) self . check_phases ( ) self . compute_spin_contamination ( ) self . frac_renormalize ( ) reference = core . get_option ( "SCF" , "REFERENCE" ) energy = self . get_energies ( "Total Energy" ) #    fail_on_maxiter = core.get_option("SCF", "FAIL_ON_MAXITER") #    if converged or not fail_on_maxiter: # #        if print_lvl > 0: #            self.print_orbitals() # #        if converged: #            core.print_out("  Energy converged.\n\n") #        else: #            core.print_out("  Energy did not converge, but proceeding anyway.\n\n") if core . get_option ( 'SCF' , 'PRINT' ) > 0 : self . print_orbitals ( ) is_dfjk = core . get_global_option ( 'SCF_TYPE' ) . endswith ( 'DF' ) core . print_out ( "  @%s%s Final Energy: %20.14f" % ( 'DF-' if is_dfjk else '' , reference , energy ) ) # if (perturb_h_) { #     core.print_out(" with %f %f %f perturbation" % #                    (dipole_field_strength_[0], dipole_field_strength_[1], dipole_field_strength_[2])) # } core . print_out ( "\n\n" ) self . print_energies ( ) self . clear_external_potentials ( ) if core . get_option ( 'SCF' , 'PCM' ) : calc_type = core . PCM . CalcType . Total if core . get_option ( "PCM" , "PCM_SCF_TYPE" ) == "SEPARATE" : calc_type = core . PCM . CalcType . NucAndEle Dt = self . Da ( ) . clone ( ) Dt . add ( self . Db ( ) ) _ , Vpcm = self . get_PCM ( ) . compute_PCM_terms ( Dt , calc_type ) self . push_back_external_potential ( Vpcm ) # Set callback function for CPSCF self . set_external_cpscf_perturbation ( "PCM" , lambda pert_dm : self . get_PCM ( ) . compute_V ( pert_dm ) ) if core . get_option ( 'SCF' , 'PE' ) : Dt = self . Da ( ) . clone ( ) Dt . add ( self . Db ( ) ) _ , Vpe = self . pe_state . get_pe_contribution ( Dt , elec_only = False ) self . push_back_external_potential ( Vpe ) # Set callback function for CPSCF self . set_external_cpscf_perturbation ( "PE" , lambda pert_dm : self . pe_state . get_pe_contribution ( pert_dm , elec_only = True ) [ 1 ] ) # Properties #  Comments so that autodoc utility will find these PSI variables #  Process::environment.globals["SCF DIPOLE X"] = #  Process::environment.globals["SCF DIPOLE Y"] = #  Process::environment.globals["SCF DIPOLE Z"] = #  Process::environment.globals["SCF QUADRUPOLE XX"] = #  Process::environment.globals["SCF QUADRUPOLE XY"] = #  Process::environment.globals["SCF QUADRUPOLE XZ"] = #  Process::environment.globals["SCF QUADRUPOLE YY"] = #  Process::environment.globals["SCF QUADRUPOLE YZ"] = #  Process::environment.globals["SCF QUADRUPOLE ZZ"] = # Orbitals are always saved, in case an MO guess is requested later # save_orbitals() # Shove variables into global space for k , v in self . variables ( ) . items ( ) : core . set_variable ( k , v ) # TODO re-enable self . finalize ( ) if self . V_potential ( ) : self . V_potential ( ) . clear_collocation_cache ( ) core . print_out ( "\nComputation Completed\n" ) core . del_variable ( "SCF D NORM" ) return energy