Charge Transfer Integrals with ADF
**********************************

ADF Fragment calculations Technical

Compute transfer integrals for a benzene dimer with ADF fragment
calculations. The workflow separates the dimer into two fragments,
runs an ADFFragmentJob, and extracts the full TransferIntegrals
section from adf.rkf.

**Requires:** AMS2026 or later

-[ Related examples ]-

* ADF Fragment Analysis Recipe

* Tuning the Range Separation Parameter in ADF

* Reduction and Oxidation Potentials

-[ Related documentation ]-

* ADF fragment analysis tutorial

[image]


Charge transfer integrals with ADF
==================================

This example computes charge-transfer integrals for a benzene dimer
with an ADF fragment calculation.


Initial Imports
---------------

   from pathlib import Path
   from typing import Dict

   from scm.plams import ADFFragmentJob, ADFFragmentResults, Molecule, Settings, view, plot_image_grid


Set up ADF Calculations
-----------------------

Set common ADF settings and enable transfer-integral analysis for the
full dimer job. A minimal basis ("SZ") is used here for speed. For
quantitative work, use a larger basis.

   common = Settings()
   common.input.ams.Task = "SinglePoint"
   common.input.adf.Basis.Type = "SZ"
   common.input.adf.Basis.Core = "None"
   common.input.adf.Symmetry = "NoSym"

   full = Settings()
   full.input.adf.transferintegrals = True


Load Benzene Dimer and Create Fragments
---------------------------------------

Load a benzene dimer, split it into two fragments, and visualize the
full dimer and fragments.

   xyz_path = Path("BenzeneDimer.xyz")
   xyz_path.write_text("""24

   C      -1.90007930      -0.01180491      -1.63051319
   C       0.87349469      -0.01023939      -1.76821915
   C      -1.20564674      -1.21381033      -1.65931829
   C      -1.20758387       1.19098295      -1.67103029
   C       0.17915587       1.19167022      -1.73987307
   C       0.18110787      -1.21293268      -1.72799219
   H      -2.98312785      -0.01239662      -1.57479944
   H      -1.74970769       2.12993064      -1.64644374
   H       0.72018058       2.13112890      -1.76828739
   H       1.95680577      -0.00959486      -1.81797251
   H       0.72362449      -2.15176759      -1.74701794
   H      -1.74626146      -2.15334648      -1.62565114
   C      -1.04276513       0.00660438       1.20777829
   C       1.73079327       0.00816985       1.07007850
   C      -0.34843214      -1.19529353       1.17943874
   C      -0.35038422       1.20928613       1.16755800
   C       1.03636300       1.21016618       1.09888633
   C       1.03830008      -1.19460875       1.11059824
   H      -2.12607520       0.00595978       1.25753750
   H      -0.89290110       2.14811978       1.18659394
   H       1.57697669       2.14970259       1.06522938
   H       2.81384166       0.00876150       1.01437093
   H       1.58042281      -2.13355664       1.08602198
   H      -0.88945704      -2.13475088       1.20786337
   """)

   dimer = Molecule(str(xyz_path))
   dimer.guess_bonds()
   fragments = dimer.separate()
   if len(fragments) != 2:
       raise RuntimeError(f"Expected 2 fragments, got {len(fragments)}")

   fragment1, fragment2 = fragments
   imgs = {
       name: view(mol, width=250, height=250)
       for name, mol in [("Dimer", dimer), ("Fragment 1", fragment1), ("Fragment 2", fragment2)]
   }
   plot_image_grid(imgs, rows=1);

   [image: image generated from notebook][image]


Run the Fragment Calculation and Extract Results
------------------------------------------------

   job = ADFFragmentJob(
       name="ADFTI",
       fragment1=fragment1,
       fragment2=fragment2,
       settings=common,
       full_settings=full,
   )
   results = job.run()

   [09.04|12:01:54] JOB ADFTI STARTED
   [09.04|12:01:54] JOB ADFTI RUNNING
   [09.04|12:01:54] JOB ADFTI/frag1 STARTED
   [09.04|12:01:54] JOB ADFTI/frag1 RUNNING
   [09.04|12:01:57] JOB ADFTI/frag1 FINISHED
   [09.04|12:01:57] JOB ADFTI/frag1 SUCCESSFUL
   [09.04|12:01:57] JOB ADFTI/frag2 STARTED
   [09.04|12:01:57] JOB ADFTI/frag2 RUNNING
   [09.04|12:01:59] JOB ADFTI/frag2 FINISHED
   [09.04|12:01:59] JOB ADFTI/frag2 SUCCESSFUL
   [09.04|12:01:59] JOB ADFTI/full STARTED
   [09.04|12:01:59] JOB ADFTI/full RUNNING
   [09.04|12:02:10] JOB ADFTI/full FINISHED
   [09.04|12:02:10] JOB ADFTI/full SUCCESSFUL
   [09.04|12:02:10] JOB ADFTI FINISHED
   [09.04|12:02:10] JOB ADFTI SUCCESSFUL

   transfer_integrals = results.job.full.results.read_rkf_section("TransferIntegrals", file="adf")
   print("== Results ==")
   for key, value in sorted(transfer_integrals.items()):
       print(f"{key:<28}: {float(value):>12.6f}")

   == Results ==
   J(charge recombination 12)  :     0.010744
   J(charge recombination 21)  :     0.010744
   J(electron)                 :     0.012050
   J(hole)                     :    -0.034988
   S(charge recombination 12)  :    -0.016229
   S(charge recombination 21)  :    -0.016229
   S(electron)                 :    -0.018755
   S(hole)                     :     0.049852
   V(charge recombination 12)  :     0.009867
   ... output trimmed ....
   V(electron)                 :     0.013129
   V(hole)                     :    -0.026790
   Vtot(charge recombination 12):     0.013193
   Vtot(charge recombination 21):     0.013193
   Vtot(electron)              :     0.021464
   Vtot(hole)                  :     0.034178
   e1(electron)                :     0.057279
   e1(hole)                    :    -0.165788
   e2(electron)                :     0.057280
   e2(hole)                    :    -0.165790


See also
========


Related examples
----------------

* ADF Fragment Analysis Recipe

* Tuning the Range Separation Parameter in ADF

* Reduction and Oxidation Potentials


Related documentation
---------------------

* ADF fragment analysis tutorial


Python Script
=============

   #!/usr/bin/env python
   # coding: utf-8

   # ## Charge transfer integrals with ADF
   #
   # This example computes charge-transfer integrals for a benzene dimer with an ADF fragment calculation.
   #

   # ### Initial Imports

   from pathlib import Path
   from typing import Dict

   from scm.plams import ADFFragmentJob, ADFFragmentResults, Molecule, Settings, view, plot_image_grid


   # ### Set up ADF Calculations

   # Set common ADF settings and enable transfer-integral analysis for the full dimer job.
   # A minimal basis (`SZ`) is used here for speed. For quantitative work, use a larger basis.

   common = Settings()
   common.input.ams.Task = "SinglePoint"
   common.input.adf.Basis.Type = "SZ"
   common.input.adf.Basis.Core = "None"
   common.input.adf.Symmetry = "NoSym"

   full = Settings()
   full.input.adf.transferintegrals = True


   # ### Load Benzene Dimer and Create Fragments

   # Load a benzene dimer, split it into two fragments, and visualize the full dimer and fragments.
   #

   xyz_path = Path("BenzeneDimer.xyz")
   xyz_path.write_text("""24

   C      -1.90007930      -0.01180491      -1.63051319
   C       0.87349469      -0.01023939      -1.76821915
   C      -1.20564674      -1.21381033      -1.65931829
   C      -1.20758387       1.19098295      -1.67103029
   C       0.17915587       1.19167022      -1.73987307
   C       0.18110787      -1.21293268      -1.72799219
   H      -2.98312785      -0.01239662      -1.57479944
   H      -1.74970769       2.12993064      -1.64644374
   H       0.72018058       2.13112890      -1.76828739
   H       1.95680577      -0.00959486      -1.81797251
   H       0.72362449      -2.15176759      -1.74701794
   H      -1.74626146      -2.15334648      -1.62565114
   C      -1.04276513       0.00660438       1.20777829
   C       1.73079327       0.00816985       1.07007850
   C      -0.34843214      -1.19529353       1.17943874
   C      -0.35038422       1.20928613       1.16755800
   C       1.03636300       1.21016618       1.09888633
   C       1.03830008      -1.19460875       1.11059824
   H      -2.12607520       0.00595978       1.25753750
   H      -0.89290110       2.14811978       1.18659394
   H       1.57697669       2.14970259       1.06522938
   H       2.81384166       0.00876150       1.01437093
   H       1.58042281      -2.13355664       1.08602198
   H      -0.88945704      -2.13475088       1.20786337
   """)

   dimer = Molecule(str(xyz_path))
   dimer.guess_bonds()
   fragments = dimer.separate()
   if len(fragments) != 2:
       raise RuntimeError(f"Expected 2 fragments, got {len(fragments)}")

   fragment1, fragment2 = fragments
   imgs = {
       name: view(mol, width=250, height=250)
       for name, mol in [("Dimer", dimer), ("Fragment 1", fragment1), ("Fragment 2", fragment2)]
   }
   plot_image_grid(imgs, rows=1, save_path="picture1.png")
   # ### Run the Fragment Calculation and Extract Results

   job = ADFFragmentJob(
       name="ADFTI",
       fragment1=fragment1,
       fragment2=fragment2,
       settings=common,
       full_settings=full,
   )
   results = job.run()


   transfer_integrals = results.job.full.results.read_rkf_section("TransferIntegrals", file="adf")
   print("== Results ==")
   for key, value in sorted(transfer_integrals.items()):
       print(f"{key:<28}: {float(value):>12.6f}")
