Excited-State Calculations with Direct Optimization
Direct optimization (DO) is an alternative to the diagonalization-based
eigensolvers, which does not use density mixing.
Since it is designed to converge to saddle point on the electronic energy surface,
this approach can be used to perform
variational calculations of excited states. The atomic forces can be obtained
directly from the method get_forces
and therefore,
the method can be used to perform geometry optimization and molecular dynamics
in the excited state.
The implementation of DO is based on the exponential transformation (see also Direct Minimization Methods) and uses efficient quasi-Newton algorithms for saddle point convergence. The real-space grid and plan-wave implementation is described in [1], while the LCAO inplementation is described in [2] and [3].
The recommended quasi-Newton algorithm is a limited-memory symmetric rank-one (L-SR1) method
[2] with unit step. In order to use this algorithm, the
following eigensolver
has to be specified:
from gpaw.directmin.lcao_etdm import LCAOETDM
calc.set(eigensolver=LCAOETDM(searchdir_algo={'name': 'l-sr1p'},
linesearch_algo={'name': 'max-step',
'max_step': 0.20})
The maximum step length avoids taking too large steps at the beginning of the wave function optimization. The default maximum step length is 0.20, which has been found to provide an adequate balance between stability and speed of convergence for calculations of excited states of molecules [2]. However, a different value might improve the convergence for specific cases.
To reduce the risk of variational collapse to lower energy solutions, DO is typically used together
with the Maximum Overlap Method. However, if the target excited state shows pronounced charge transfer character, variational
collapse can sometimes not be prevented even if DO and MOM are used in conjunction. In
such cases, it can be worthwhile to first perform a constrained optimization in which the
electron and hole orbitals involved in the target excitation are frozen, and a
minimization is done in the remaining subspace, before performing a full unconstrained
optimization. The constrained minimization takes care of a large part of the prominent
orbital relaxation effect in charge transfer excited states and thereby significantly
simplifies the subsequent saddle point search, preventing variational collapse.
Constrained optimization can be performed by using the constraints
keyword:
calc.set(eigensolver=LCAOETDM(constraints=[[[h11], [h12],..., [p11], [p12],...],
[[h21], [h22],..., [p21], [p22],...],
...])
Each hij
refers to the index of the j
-th hole in the i
-th K-point,
each pij
to the index of the j-th excited electron in the i
-th K-point.
For example, if an excited state calculation is initialize by promoting an electron
from the ground state HOMO to the ground state LUMO, one needs to specify the indices
of the ground state HOMO (hole) and LUMO (excited electron) in the spin channel where
the excitation is performed.
All rotations involving these orbitals are frozen during the constrained optimization
resulting in these orbitals remaining unaltered after the optimization. It is
also possible to constrain selected orbital rotations without completely
freezing the involved orbitals by specifying lists of two orbital indices
instead of lists of single orbital indices. However, care has to be taken
in that case since constraining a single orbital rotation may not fully
prevent mixing between those two orbitals during the constrained
optimization.
Charge transfer excited state of N-phenylpyrrole
In this example, a calculation of a charge transfer excited state of the N-phenylpyrrole molecule is carried out. After a ground state calculation, a single excitation is performed from the HOMO to the LUMO in one spin channel. No spin purification is used, meaning that only the mixed-spin open-shell determinant is optimized. If an unconstrained optimization is performed from this initial guess, the calculation collapses to a first-order saddle point with pronounced mixing between the HOMO and LUMO and a small dipole moment of -3.396 D, which is not consistent with the wanted charge transfer excited state. Variational collapse is avoided here by performing first a constrained optimization freezing the hole and excited electron of the initial guess. Then the new orbitals are used as the initial guess of an unconstrained optimization, which converges to a higher-energy saddle point with a large dipole moment of -10.227 D consistent with the target charge transfer state.
from ase.io import read
from gpaw import GPAW, LCAO
from gpaw.mom import prepare_mom_calculation
from gpaw.directmin.tools import excite
from gpaw.directmin.etdm_lcao import LCAOETDM
calc = GPAW(xc='PBE',
mode=LCAO(),
h=0.2,
basis='dzp',
spinpol=True,
eigensolver='etdm-lcao',
occupations={'name': 'fixed-uniform'},
mixer={'backend': 'no-mixing'},
nbands='nao',
symmetry='off',
txt='N-Phenylpyrrole_GS.txt')
atoms = read('N-Phenylpyrrole.xyz')
atoms.center(vacuum=5.0)
atoms.set_pbc(False)
atoms.calc = calc
# Ground state calculation
E_GS = atoms.get_potential_energy()
# Ground state LCAO coefficients and occupation numbers
C_GS = [calc.wfs.kpt_u[x].C_nM.copy() for x in range(len(calc.wfs.kpt_u))]
f_gs = [calc.wfs.kpt_u[x].f_n.copy() for x in range(len(calc.wfs.kpt_u))]
# Direct approach using ground state orbitals with changed occupation numbers
calc.set(eigensolver=LCAOETDM(searchdir_algo={'name': 'l-sr1p'},
linesearch_algo={'name': 'max-step'},
need_init_orbs=False),
txt='N-Phenylpyrrole_EX_direct.txt')
# Spin-mixed open-shell occupation numbers
f = excite(calc, 0, 0, spin=(0, 0))
# Direct optimization maximum overlap method calculation
prepare_mom_calculation(calc, atoms, f)
E_EX_direct = atoms.get_potential_energy()
# Reset LCAO coefficients and occupation numbers to ground state solution
for k, kpt in enumerate(calc.wfs.kpt_u):
kpt.C_nM = C_GS[k]
kpt.f_n = f_gs[k]
h = 26 # Hole
p = 27 # Excited electron
# Constrained optimization freezing hole and excited electron
calc.set(eigensolver=LCAOETDM(constraints=[[[h], [p]], []],
need_init_orbs=False),
txt='N-Phenylpyrrole_EX_constrained.txt')
# Spin-mixed open-shell occupation numbers
f = excite(calc, 0, 0, spin=(0, 0))
# Direct optimization maximum overlap method calculation
prepare_mom_calculation(calc, atoms, f)
E_EX_constrained = atoms.get_potential_energy()
# Unconstrained optimization using constrained solution as initial guess
calc.set(eigensolver=LCAOETDM(searchdir_algo={'name': 'l-sr1p'},
linesearch_algo={'name': 'max-step'},
need_init_orbs=False),
txt='N-Phenylpyrrole_EX_from_constrained.txt')
# Direct optimization maximum overlap method calculation
E_EX_from_constrained = atoms.get_potential_energy()
Excited state of silicon using plane wave
In this example, the singlet excited state of a conventional silicon is calculated using plane waves approach.
from gpaw import GPAW
from ase.build import bulk
from gpaw.directmin.etdm_fdpw import FDPWETDM
from gpaw.mom import prepare_mom_calculation
from gpaw.directmin.tools import excite
from ase.parallel import paropen
atoms = bulk('Si', 'diamond', a=5.44, cubic=True)
atoms.cell[0, 0] += 1e-3
# Step: Set up the GPAW calculator
calc = GPAW(mode={'name': 'pw', # Use plane wave mode
'ecut': 340}, # Cutoff energy
xc='PBE',
kpts=(1, 1, 1),
eigensolver=FDPWETDM(converge_unocc=True),
mixer={'backend': 'no-mixing'},
occupations={'name': 'fixed-uniform'},
spinpol=True,
)
atoms.calc = calc
E_gs = atoms.get_potential_energy()
calc.set(eigensolver=FDPWETDM(excited_state=True,
converge_unocc=False,
momevery=10,
max_step_inner_loop=0.2,
maxiter_inner_loop=20))
f_sn = excite(calc, 0, 0, (0, 0))
prepare_mom_calculation(calc, atoms, f_sn)
E_es = atoms.get_potential_energy()
print(f'Excitation energy: {E_es - E_gs}')
with paropen('si_excited.txt', 'w') as fd:
print(f'Excitation energy Si: {E_es - E_gs} eV',
file=fd)