Vibronic Density of States with ADF¶
This example uses ADF to model the density of states involved in the charge transfer between two systems using the AH-FC method.
Example usage: (no2_1.xyz
,
no2_2.xyz
,
fcf_dos.py
)
3
Neutral NO2
N 0.00000000 -0.00000000 -0.01857566
O 0.00000000 1.09915770 -0.49171967
O -0.00000000 -1.09915770 -0.49171967
3
Anion NO2
N 0.000000 0.000000 0.126041
O 0.000000 1.070642 -0.555172
O 0.000000 -1.070642 -0.555172
from scm.plams import Settings, AMSJob, Molecule, Atom, FCFJob, init
from scm.plams.recipes.fcf_dos import FCFDOS
# This is a simplified PLAMS script to calculate the density of states (DOS)
# for the transfer between two systems, in this case NO2 radical and NO2 anion
# We start from pre-optimized geometries to save time, though normally the
# geometry optimization should come first, then we calculate the frequencies
# for both systems and finally the absorption and emission FCF spectra
# and finally the DOS is calculated from the FCF spectra using the FCFDOS utility
# implemented in PLAMS
# Pre-optimized geometries
geom_1 = "no2_1.xyz"
geom_2 = "no2_2.xyz"
def freq(mol, common, pdir):
"""Frequency calculation"""
# Define settings
settings = Settings()
settings.update(common)
settings.input.ams.Properties.NormalModes = "Yes"
settings.input.adf.title = "Vibrational frequencies"
# Run job
frqjob = AMSJob(molecule=mol, settings=settings, name=pdir)
results = frqjob.run()
return results
def fcf(job1, job2, spctype, pdir):
"""FCF Job"""
setfcf = Settings()
setfcf.input.spectrum.type = spctype
setfcf.input.state1 = job1.rkfpath(file="adf")
setfcf.input.state2 = job2.rkfpath(file="adf")
fcfjob = FCFJob(inputjob1=job1.rkfpath(file="adf"), inputjob2=job2.rkfpath(file="adf"), settings=setfcf, name=pdir)
results = fcfjob.run()
return results
def main():
init()
# Common settings
settings = Settings()
settings.input.adf.symmetry = "NoSym"
settings.input.adf.basis.type = "DZP"
settings.input.adf.basis.core = "None"
settings.input.adf.xc.lda = "SCF VWN"
settings.input.ams.Task = "SinglePoint"
# mol1 = Molecule(filename=geom_1)
mol1 = Molecule()
mol1.add_atom(Atom(atnum=7, coords=(0.0, 0.0, -0.01857566)))
mol1.add_atom(Atom(atnum=8, coords=(0.0, 1.09915770, -0.49171967)))
mol1.add_atom(Atom(atnum=8, coords=(0.0, -1.09915770, -0.49171967)))
# mol2 = Molecule(filename=geom_2)
mol2 = Molecule()
mol2.add_atom(Atom(atnum=7, coords=(0.0, 0.0, 0.12041)))
mol2.add_atom(Atom(atnum=8, coords=(0.0, 1.070642, -0.555172)))
mol2.add_atom(Atom(atnum=8, coords=(0.0, -1.070642, -0.555172)))
# Acceptor vibrational frequencies calculation
set1 = Settings()
set1.update(settings)
set1.input.ams.system.charge = 0
set1.input.adf.spinpolarization = 1
set1.input.adf.unrestricted = "Yes"
frq1 = freq(mol1, set1, "gsmol1")
# Donor vibrational frequencies calculation
set2 = Settings()
set2.update(settings)
set2.input.ams.system.charge = -1
frq2 = freq(mol2, set2, "gsmol2")
# FCF jobs to calculate the vibronic spectra
fcfabs = fcf(frq1, frq2, "absorption", "fcfabs")
fcfemi = fcf(frq2, frq1, "emission", "fcfemi")
# DOS calculation
job = FCFDOS(fcfabs._kf.path, fcfabs._kf.path, 10000.0, 10000.0)
dos = job.dos()
print(f"The density of states is {dos:.5e}")
return None
main()