parameters: (dimer_wfn, wfn_A, wfn_B, sapt_jk=None, sapt_jk_B=None, data=None, print_header=True, cleanup_jk=True)
return_statement: return data
docstring: The primary SAPT(DFT) algorithm to compute the interaction energy once the wavefunctions have been built.
  
      Example
      -------
  
      dimer = psi4.geometry('''
        Ne
        --
        Ar 1 6.5
        units bohr
      ''')
  
      psi4.set_options({"BASIS": "aug-cc-pVDZ"})
  
      # Prepare the fragments
      sapt_dimer, monomerA, monomerB = psi4.proc_util.prepare_sapt_molecule(sapt_dimer, "dimer")
  
      # Run the first monomer
      set DFT_GRAC_SHIFT 0.203293
      wfnA, energyA = psi4.energy("PBE0", monomer=monomerA, return_wfn=True)
  
      # Run the second monomer
      set DFT_GRAC_SHIFT 0.138264
      wfnB, energyB = psi4.energy("PBE0", monomer=monomerB, return_wfn=True)
  
      # Build the dimer wavefunction
      wfnD = psi4.core.Wavefunction.build(sapt_dimer)
  
      # Compute SAPT(DFT) from the provided wavefunctions
      data = psi4.procrouting.sapt.sapt_dft(wfnD, wfnA, wfnB)
docstring_summary: The primary SAPT(DFT) algorithm to compute the interaction energy once the wavefunctions have been built.
docstring_tokens: The primary SAPT ( DFT ) algorithm to compute the interaction energy once the wavefunctions have been built .
function: def sapt_dft(dimer_wfn, wfn_A, wfn_B, sapt_jk=None, sapt_jk_B=None, data=None, print_header=True, cleanup_jk=True):
      """
      The primary SAPT(DFT) algorithm to compute the interaction energy once the wavefunctions have been built.
  
      Example
      -------
  
      dimer = psi4.geometry('''
        Ne
        --
        Ar 1 6.5
        units bohr
      ''')
  
      psi4.set_options({"BASIS": "aug-cc-pVDZ"})
  
      # Prepare the fragments
      sapt_dimer, monomerA, monomerB = psi4.proc_util.prepare_sapt_molecule(sapt_dimer, "dimer")
  
      # Run the first monomer
      set DFT_GRAC_SHIFT 0.203293
      wfnA, energyA = psi4.energy("PBE0", monomer=monomerA, return_wfn=True)
  
      # Run the second monomer
      set DFT_GRAC_SHIFT 0.138264
      wfnB, energyB = psi4.energy("PBE0", monomer=monomerB, return_wfn=True)
  
      # Build the dimer wavefunction
      wfnD = psi4.core.Wavefunction.build(sapt_dimer)
  
      # Compute SAPT(DFT) from the provided wavefunctions
      data = psi4.procrouting.sapt.sapt_dft(wfnD, wfnA, wfnB)
      """
  
      # Handle the input options
      core.timer_on("SAPT(DFT):SAPT(DFT):Build JK")
      if print_header:
          sapt_dft_header()
  
      if sapt_jk is None:
  
          core.print_out("\n   => Building SAPT JK object <= \n\n")
          sapt_jk = core.JK.build(dimer_wfn.basisset())
          sapt_jk.set_do_J(True)
          sapt_jk.set_do_K(True)
          if wfn_A.functional().is_x_lrc():
              sapt_jk.set_do_wK(True)
              sapt_jk.set_omega(wfn_A.functional().x_omega())
          sapt_jk.initialize()
          sapt_jk.print_header()
  
          if wfn_B.functional().is_x_lrc() and (wfn_A.functional().x_omega() != wfn_B.functional().x_omega()):
              core.print_out("   => Monomer B: Building SAPT JK object <= \n\n")
              core.print_out("      Reason: MonomerA Omega != MonomerB Omega\n\n")
              sapt_jk_B = core.JK.build(dimer_wfn.basisset())
              sapt_jk_B.set_do_J(True)
              sapt_jk_B.set_do_K(True)
              sapt_jk_B.set_do_wK(True)
              sapt_jk_B.set_omega(wfn_B.functional().x_omega())
              sapt_jk_B.initialize()
              sapt_jk_B.print_header()
      else:
          sapt_jk.set_do_K(True)
  
      if data is None:
          data = {}
  
      # Build SAPT cache
      cache = sapt_jk_terms.build_sapt_jk_cache(wfn_A, wfn_B, sapt_jk, True)
      core.timer_off("SAPT(DFT):SAPT(DFT):Build JK")
  
      # Electrostatics
      core.timer_on("SAPT(DFT):SAPT(DFT):elst")
      elst = sapt_jk_terms.electrostatics(cache, True)
      data.update(elst)
      core.timer_off("SAPT(DFT):SAPT(DFT):elst")
  
      # Exchange
      core.timer_on("SAPT(DFT):SAPT(DFT):exch")
      exch = sapt_jk_terms.exchange(cache, sapt_jk, True)
      data.update(exch)
      core.timer_off("SAPT(DFT):SAPT(DFT):exch")
  
      # Induction
      core.timer_on("SAPT(DFT):SAPT(DFT):ind")
      ind = sapt_jk_terms.induction(cache,
                                    sapt_jk,
                                    True,
                                    sapt_jk_B=sapt_jk_B,
                                    maxiter=core.get_option("SAPT", "MAXITER"),
                                    conv=core.get_option("SAPT", "D_CONVERGENCE"),
                                    Sinf=core.get_option("SAPT", "DO_IND_EXCH_SINF"))
      data.update(ind)
      core.timer_off("SAPT(DFT):SAPT(DFT):ind")
  
      # Blow away JK object before doing MP2 for memory considerations
      if cleanup_jk:
          sapt_jk.finalize()
  
      # Hybrid xc kernel check
      do_hybrid = core.get_option("SAPT", "SAPT_DFT_DO_HYBRID")
      is_x_hybrid = wfn_B.functional().is_x_hybrid()
      is_x_lrc = wfn_B.functional().is_x_lrc()
      hybrid_specified = core.has_option_changed("SAPT", "SAPT_DFT_DO_HYBRID")
      if is_x_lrc:
          if do_hybrid:
              if hybrid_specified:
                  raise ValidationError(
                      "SAPT(DFT): Hybrid xc kernel not yet implemented for range-separated funtionals.")
              else:
                  core.print_out(
                      "Warning: Hybrid xc kernel not yet implemented for range-separated funtionals; hybrid kernel capability is turned off.\n"
                  )
          is_hybrid = False
      else:
          if do_hybrid:
              is_hybrid = is_x_hybrid
          else:
              is_hybrid = False
  
      # Dispersion
      core.timer_on("SAPT(DFT):SAPT(DFT):disp")
      primary_basis = wfn_A.basisset()
      core.print_out("\n")
      aux_basis = core.BasisSet.build(dimer_wfn.molecule(), "DF_BASIS_MP2", core.get_option("DFMP2", "DF_BASIS_MP2"),
                                      "RIFIT", core.get_global_option('BASIS'))
      x_alpha = wfn_B.functional().x_alpha()
      if not is_hybrid:
          x_alpha = 0.0
      fdds_disp = sapt_mp2_terms.df_fdds_dispersion(primary_basis, aux_basis, cache, is_hybrid, x_alpha)
      data.update(fdds_disp)
  
      if core.get_option("SAPT", "SAPT_DFT_MP2_DISP_ALG") == "FISAPT":
          mp2_disp = sapt_mp2_terms.df_mp2_fisapt_dispersion(wfn_A, primary_basis, aux_basis, cache, do_print=True)
      else:
          mp2_disp = sapt_mp2_terms.df_mp2_sapt_dispersion(dimer_wfn,
                                                           wfn_A,
                                                           wfn_B,
                                                           primary_basis,
                                                           aux_basis,
                                                           cache,
                                                           do_print=True)
      data.update(mp2_disp)
      core.timer_off("SAPT(DFT):SAPT(DFT):disp")
  
      # Print out final data
      core.print_out("\n")
      core.print_out(print_sapt_dft_summary(data, "SAPT(DFT)"))
  
      return data
function_tokens: def sapt_dft ( dimer_wfn , wfn_A , wfn_B , sapt_jk = None , sapt_jk_B = None , data = None , print_header = True , cleanup_jk = True ) : # Handle the input options core . timer_on ( "SAPT(DFT):SAPT(DFT):Build JK" ) if print_header : sapt_dft_header ( ) if sapt_jk is None : core . print_out ( "\n   => Building SAPT JK object <= \n\n" ) sapt_jk = core . JK . build ( dimer_wfn . basisset ( ) ) sapt_jk . set_do_J ( True ) sapt_jk . set_do_K ( True ) if wfn_A . functional ( ) . is_x_lrc ( ) : sapt_jk . set_do_wK ( True ) sapt_jk . set_omega ( wfn_A . functional ( ) . x_omega ( ) ) sapt_jk . initialize ( ) sapt_jk . print_header ( ) if wfn_B . functional ( ) . is_x_lrc ( ) and ( wfn_A . functional ( ) . x_omega ( ) != wfn_B . functional ( ) . x_omega ( ) ) : core . print_out ( "   => Monomer B: Building SAPT JK object <= \n\n" ) core . print_out ( "      Reason: MonomerA Omega != MonomerB Omega\n\n" ) sapt_jk_B = core . JK . build ( dimer_wfn . basisset ( ) ) sapt_jk_B . set_do_J ( True ) sapt_jk_B . set_do_K ( True ) sapt_jk_B . set_do_wK ( True ) sapt_jk_B . set_omega ( wfn_B . functional ( ) . x_omega ( ) ) sapt_jk_B . initialize ( ) sapt_jk_B . print_header ( ) else : sapt_jk . set_do_K ( True ) if data is None : data = { } # Build SAPT cache cache = sapt_jk_terms . build_sapt_jk_cache ( wfn_A , wfn_B , sapt_jk , True ) core . timer_off ( "SAPT(DFT):SAPT(DFT):Build JK" ) # Electrostatics core . timer_on ( "SAPT(DFT):SAPT(DFT):elst" ) elst = sapt_jk_terms . electrostatics ( cache , True ) data . update ( elst ) core . timer_off ( "SAPT(DFT):SAPT(DFT):elst" ) # Exchange core . timer_on ( "SAPT(DFT):SAPT(DFT):exch" ) exch = sapt_jk_terms . exchange ( cache , sapt_jk , True ) data . update ( exch ) core . timer_off ( "SAPT(DFT):SAPT(DFT):exch" ) # Induction core . timer_on ( "SAPT(DFT):SAPT(DFT):ind" ) ind = sapt_jk_terms . induction ( cache , sapt_jk , True , sapt_jk_B = sapt_jk_B , maxiter = core . get_option ( "SAPT" , "MAXITER" ) , conv = core . get_option ( "SAPT" , "D_CONVERGENCE" ) , Sinf = core . get_option ( "SAPT" , "DO_IND_EXCH_SINF" ) ) data . update ( ind ) core . timer_off ( "SAPT(DFT):SAPT(DFT):ind" ) # Blow away JK object before doing MP2 for memory considerations if cleanup_jk : sapt_jk . finalize ( ) # Hybrid xc kernel check do_hybrid = core . get_option ( "SAPT" , "SAPT_DFT_DO_HYBRID" ) is_x_hybrid = wfn_B . functional ( ) . is_x_hybrid ( ) is_x_lrc = wfn_B . functional ( ) . is_x_lrc ( ) hybrid_specified = core . has_option_changed ( "SAPT" , "SAPT_DFT_DO_HYBRID" ) if is_x_lrc : if do_hybrid : if hybrid_specified : raise ValidationError ( "SAPT(DFT): Hybrid xc kernel not yet implemented for range-separated funtionals." ) else : core . print_out ( "Warning: Hybrid xc kernel not yet implemented for range-separated funtionals; hybrid kernel capability is turned off.\n" ) is_hybrid = False else : if do_hybrid : is_hybrid = is_x_hybrid else : is_hybrid = False # Dispersion core . timer_on ( "SAPT(DFT):SAPT(DFT):disp" ) primary_basis = wfn_A . basisset ( ) core . print_out ( "\n" ) aux_basis = core . BasisSet . build ( dimer_wfn . molecule ( ) , "DF_BASIS_MP2" , core . get_option ( "DFMP2" , "DF_BASIS_MP2" ) , "RIFIT" , core . get_global_option ( 'BASIS' ) ) x_alpha = wfn_B . functional ( ) . x_alpha ( ) if not is_hybrid : x_alpha = 0.0 fdds_disp = sapt_mp2_terms . df_fdds_dispersion ( primary_basis , aux_basis , cache , is_hybrid , x_alpha ) data . update ( fdds_disp ) if core . get_option ( "SAPT" , "SAPT_DFT_MP2_DISP_ALG" ) == "FISAPT" : mp2_disp = sapt_mp2_terms . df_mp2_fisapt_dispersion ( wfn_A , primary_basis , aux_basis , cache , do_print = True ) else : mp2_disp = sapt_mp2_terms . df_mp2_sapt_dispersion ( dimer_wfn , wfn_A , wfn_B , primary_basis , aux_basis , cache , do_print = True ) data . update ( mp2_disp ) core . timer_off ( "SAPT(DFT):SAPT(DFT):disp" ) # Print out final data core . print_out ( "\n" ) core . print_out ( print_sapt_dft_summary ( data , "SAPT(DFT)" ) ) return data