def make_force_sets_and_excitations(cachepath, disp_filenames, phonon, atoms, ex_kw): if os.path.exists(cachepath): parprint(f'Found existing {cachepath}') return np.load(cachepath) world.barrier() parprint( f'Computing force sets and polarizability data at displacements... ({cachepath})' ) eq_atoms = atoms.copy() def iter_displacement_files(): eq_force_filename = disp_filenames['force']['eq'] eq_ex_filename = disp_filenames['ex']['eq'] yield 'eq', eq_force_filename, eq_ex_filename, eq_atoms disp_phonopy_sites, disp_carts = get_phonopy_displacements(phonon) for i, disp_atoms in enumerate( iter_displaced_structures(atoms, disp_phonopy_sites, disp_carts)): force_filename = disp_filenames['force']['disp'].format(i) ex_filename = disp_filenames['ex']['disp'].format(i) yield 'disp', force_filename, ex_filename, disp_atoms # Make files for one displacement at a time for disp_kind, force_filename, ex_filename, disp_atoms in iter_displacement_files( ): if os.path.exists(ex_filename): continue world.barrier() atoms.set_positions(disp_atoms.get_positions()) disp_forces = atoms.get_forces() ex = LrTDDFT(atoms.calc, **ex_kw) if disp_kind == 'eq': # For inspecting the impact of differences in the calculator # between ionic relaxation and raman computation. parprint('Max equilibrium force during raman:', np.absolute(disp_forces).max()) if world.rank == 0: np.save(force_filename, disp_forces) ex.write(ex_filename) # combine force sets into one file force_sets = np.array([ np.load(disp_filenames['force']['disp'].format(i)) for i in range(len(phonon.get_displacements())) ]) np.save(cachepath, force_sets) for i in range(len(phonon.get_displacements())): os.unlink(disp_filenames['force']['disp'].format(i)) return force_sets
el = obj(calc, energy_range=8, txt=txt) if hasattr(obj, 'diagonalize'): el.diagonalize() # print "*************** obj, len(obj)", obj.__name__, len(el) assert len(el) == 4 el = obj(calc, energy_range=11.5, txt=txt) # print "*************** obj, len(obj)", obj.__name__, len(el) if hasattr(obj, 'diagonalize'): el.diagonalize() assert len(el) == 18 if hasattr(obj, 'diagonalize'): el.diagonalize(energy_range=8) assert len(el) == 4 lr = LrTDDFT(calc, nspins=2) lr.write('lrtddft3.dat.gz') lr.diagonalize() world.barrier() # This is done to test if writing and reading again yields the same result lr2 = LrTDDFT('lrtddft3.dat.gz') lr2.diagonalize() # Unfortunately not all of the lrtddft code is parallel if rank == 0: Epeak = 19.5 # The peak we want to investigate (this is alone) Elist = np.asarray([lrsingle.get_energy() * Hartree for lrsingle in lr]) n = np.argmin(np.abs(Elist - Epeak)) # Index of the peak E = lr[n].get_energy() * Hartree
lr_spin.diagonalize() for i in range(2): print 'i, real, virtual spin: ', i, lr_vspin[i], lr_spin[i] equal(lr_vspin[i].get_energy(), lr_spin[i].get_energy(), 5.e-6) # singlet/triplet separation precision = 1.e-5 singlet.diagonalize() equal(singlet[0].get_energy(), lr_spin[1].get_energy(), precision) equal(singlet[0].get_oscillator_strength()[0], lr_spin[1].get_oscillator_strength()[0], precision) triplet.diagonalize() equal(triplet[0].get_oscillator_strength()[0], 0) equal(triplet[0].get_energy(), lr_spin[0].get_energy(), precision) equal(triplet[0].get_oscillator_strength()[0], 0) # io fname = 'lr.dat.gz' if not io_only: lr.write(fname) world.barrier() lr = LrTDDFT(fname) lr.diagonalize() t4 = lr[0] if not io_only: equal(t3.get_energy(), t4.get_energy(), 1e-6) e4 = t4.get_energy() equal(e4, 0.675814, 1e-4)
from gpaw import GPAW from gpaw.lrtddft import LrTDDFT c = GPAW('Be_gs_8bands.gpw') istart = 0 # band index of the first occ. band to consider jend = 8 # band index of the last unocc. band to consider lr = LrTDDFT(c, xc='LDA', istart=istart, jend=jend, nspins=2) # force the calculation of triplet excitations also lr.write('lr.dat.gz')
from ase import Atoms from gpaw import GPAW from gpaw.lrtddft import LrTDDFT # Na2 cluster atoms = Atoms(symbols='Na2', positions=[(0, 0, 0), (3.0, 0, 0)], pbc=False) atoms.center(vacuum=6.0) # Standard ground state calculation with empty states calc = GPAW(nbands=100, h=0.4, setups={'Na': '1'}) atoms.set_calculator(calc) energy = atoms.get_potential_energy() calc.set(convergence={'bands' : 90}, fixdensity=True, eigensolver='cg') calc.calculate() calc.write('na2_gs_casida.gpw', mode='all') # Standard Casida calculation calc = GPAW('na2_gs_casida.gpw') istart = 0 jend = 90 lr = LrTDDFT(calc, xc='LDA', istart=istart, jend=jend) lr.diagonalize() lr.write('na2_lr.dat.gz')
pes.save_folded_pes(filename=None, folding=None) # check for correct shift VDE = calc_plus.get_potential_energy() - calc.get_potential_energy() BE_HOMO = 1.e23 be_n, f_n = pes.get_energies_and_weights() for be, f in zip(be_n, f_n): if f > 0.1 and be < BE_HOMO: BE_HOMO = be equal(BE_HOMO, VDE) lr = LrTDDFT(calc_plus, xc=xc) out = 'lrpes.dat' pes = TDDFTPES(calc, lr) pes.save_folded_pes(filename=out, folding='Gauss') pes.save_folded_pes(filename=None, folding=None) energy_tolerance = 0.0001 niter_tolerance = 1 equal(e_H2, -3.90059, energy_tolerance) equal(e_H2_plus, 10.5659703, energy_tolerance) # io out = 'lrpes.dat.gz' lr.write(out) lr = LrTDDFT(out) lr.set_calculator(calc_plus) pes = TDDFTPES(calc, lr) pes.save_folded_pes(filename=None, folding=None)
) start = time.time() # Load calculator after relaxing empty structure calc = GPAW('emptyCalc.gpw') calc.set(txt='spec.gpaw-out') # Calculate and diagonalize Omega matrix dE = 6 # Up to 6 eV transitions considered lr = LrTDDFT( calc, xc='LDA', energy_range=dE, ) # Construct the omega matrix, parallelised over all available cores lr.write(f'lr_dE={dE}eV.dat.gz') # Save the tdDFT calculater just in case lr.diagonalize() wd = 0.06 photoabsorption_spectrum(lr, f'spectrum_w{wd}.dat', width=wd) # Save results for task 2 lr.write('TDDFT_Task1.dat') end = time.time() if world.rank == 0: print('-------- Photoabsorption spectrum extracted in: ' + f'{(end-start):.2f} s --------'.rjust(34)) print( '----------------------------------------------------------------------' )
# singlet/triplet separation precision = 1.e-5 singlet.diagonalize() equal(singlet[0].get_energy(), lr_spin[1].get_energy(), precision) equal(singlet[0].get_oscillator_strength()[0], lr_spin[1].get_oscillator_strength()[0], precision) triplet.diagonalize() equal(triplet[0].get_oscillator_strength()[0], 0) equal(triplet[0].get_energy(), lr_spin[0].get_energy(), precision) equal(triplet[0].get_oscillator_strength()[0], 0) # io fname = 'lr.dat.gz' if not io_only: lr.write(fname) world.barrier() lr = LrTDDFT(fname) lr.diagonalize() t4 = lr[0] if not io_only: equal(t3.get_energy(), t4.get_energy(), 1e-6) e4 = t4.get_energy() equal(e4, 0.675814, 2e-4) # excited state with forces accuracy = 0.3 exst = ExcitedState(lr_calc, 0) forces = exst.get_forces(H2)
if setup_paths[0] != '.': setup_paths.insert(0, '.') gen('Mg', xcname='PBE', scalarrel=True, exx=True, yukawa_gamma=0.38) c = {'energy': 0.05, 'eigenstates': 3, 'density': 3} na2 = Cluster(Atoms('Mg', positions=[[0, 0, 0]])) na2.minimal_box(2.5, h=h) calc = GPAW(txt='mg_ivo.txt', xc='LCY-PBE:omega=0.38:excitation=singlet', eigensolver=RMMDIIS(), h=h, occupations=FermiDirac(width=0.0), spinpol=False, convergence=c) na2.set_calculator(calc) na2.get_potential_energy() (eps_homo, eps_lumo) = calc.get_homo_lumo() e_ex = eps_lumo - eps_homo equal(e_singlet, e_ex, 0.15) calc.write('mg.gpw') c2 = GPAW('mg.gpw') assert c2.hamiltonian.xc.excitation == 'singlet' lr = LrTDDFT(calc, txt='LCY_TDDFT_Mg.log', istart=4, jend=5, nspins=2) lr.write('LCY_TDDFT_Mg.ex.gz') if world.rank == 0: lr2 = LrTDDFT('LCY_TDDFT_Mg.ex.gz') lr2.diagonalize() ex_lr = lr2[1].get_energy() * Hartree equal(e_singlet_lr, ex_lr, 0.15)
h=0.3, occupations=FermiDirac(width=0.0, fixmagmom=True)) calc = get_paw() calc.set(txt='H2O_LCY_PBE_083.log') calc_plus = get_paw() calc_plus.set(txt='H2O_plus_LCY_PBE_083.log', charge=1) h2o.set_calculator(calc) e_h2o = h2o.get_potential_energy() h2o_plus.set_calculator(calc_plus) e_h2o_plus = h2o_plus.get_potential_energy() e_ion = e_h2o_plus - e_h2o print(e_ion, 12.62) equal(e_ion, 12.62, 0.1) lr = LrTDDFT(calc_plus, txt='LCY_TDDFT_H2O.log', jend=4) equal(lr.xc.omega, 0.83) lr.write('LCY_TDDFT_H2O.ex.gz') # reading is problematic with EXX on more than one core if world.rank == 0: lr2 = LrTDDFT('LCY_TDDFT_H2O.ex.gz') lr2.diagonalize() equal(lr2.xc.omega, 0.83) for i, ip_i in enumerate([14.74, 18.51]): ion_i = lr2[i].get_energy() * Hartree + e_ion print(ion_i, ip_i) equal(ion_i, ip_i, 0.6)
from gpaw import GPAW from gpaw.lrtddft import LrTDDFT c = GPAW('Be_gs_8bands.gpw') dE = 10 # maximal Kohn-Sham transition energy to consider in eV lr = LrTDDFT(c, xc='LDA', energy_range=dE) lr.write('lr_dE.dat.gz')
from gpaw import GPAW from gpaw.lrtddft import LrTDDFT c = GPAW('Be_gs_8bands.gpw') istart=0 # band index of the first occ. band to consider jend=8 # band index of the last unocc. band to consider lr = LrTDDFT(c, xc='LDA', istart=istart, jend=jend, nspins=2) # force the calculation of triplet excitations also lr.write('lr.dat.gz')
from gpaw.lrtddft import LrTDDFT, photoabsorption_spectrum lr = LrTDDFT(filename='Omega_Na2.gz') lr.diagonalize() lr.write('excitations_Na2.gz') lr = LrTDDFT(filename='excitations_Na2.gz') photoabsorption_spectrum(lr, 'Na2_spectrum.dat', e_min=0.0, e_max=10)
if setup_paths[0] != '.': setup_paths.insert(0, '.') gen('Na', xcname='PBE', scalarrel=True, exx=True, yukawa_gamma=0.40) gen('Cl', xcname='PBE', scalarrel=True, exx=True, yukawa_gamma=0.40) c = {'energy': 0.005, 'eigenstates': 1e-2, 'density': 1e-2} mol = Cluster(molecule('NaCl')) mol.minimal_box(5.0, h=h) calc = GPAW(txt='NaCl.txt', xc='LCY-PBE:omega=0.40:excitation=singlet', eigensolver=RMMDIIS(), h=h, occupations=FermiDirac(width=0.0), spinpol=False, convergence=c) mol.set_calculator(calc) mol.get_potential_energy() (eps_homo, eps_lumo) = calc.get_homo_lumo() e_ex = eps_lumo - eps_homo equal(e_singlet, e_ex, 0.15) calc.write('NaCl.gpw') lr = LrTDDFT(calc, txt='LCY_TDDFT_NaCl.log', istart=6, jend=7, nspins=2) lr.write('LCY_TDDFT_NaCl.ex.gz') if world.rank == 0: lr2 = LrTDDFT('LCY_TDDFT_NaCl.ex.gz') lr2.diagonalize() ex_lr = lr2[1].get_energy() * Hartree equal(e_singlet_lr, e_singlet, 0.05)
from ase import Atoms from gpaw import GPAW from gpaw.lrtddft import LrTDDFT # Na2 cluster atoms = Atoms(symbols='Na2', positions=[(0, 0, 0), (3.0, 0, 0)], pbc=False) atoms.center(vacuum=6.0) # Standard ground state calculation with empty states calc = GPAW(nbands=100, h=0.4, setups={'Na': '1'}) atoms.set_calculator(calc) energy = atoms.get_potential_energy() calc.set(convergence={'bands': 90}, fixdensity=True, eigensolver='cg') atoms.get_potential_energy() calc.write('na2_gs_casida.gpw', mode='all') # Standard Casida calculation calc = GPAW('na2_gs_casida.gpw') istart = 0 jend = 90 lr = LrTDDFT(calc, xc='LDA', istart=istart, jend=jend) lr.diagonalize() lr.write('na2_lr.dat.gz')
from gpaw import restart from gpaw.lrtddft import LrTDDFT, photoabsorption_spectrum atoms, calc = restart('na2_gs_unocc.gpw') # Calculate the omega matrix lr = LrTDDFT(calc, xc='LDA', jend=5) # Use only 5 unoccupied states # Save the omega matrix lr.write('Omega_Na2.gz') # Diagonalize the matrix lr.diagonalize() # Analyse 5 lowest excitations lr.analyse(range(5)) photoabsorption_spectrum(lr, 'Na2_spectrum.dat', e_min=0.0, e_max=10)
# check for correct shift VDE = calc_plus.get_potential_energy() - calc.get_potential_energy() BE_HOMO = 1.e23 be_n, f_n = pes.get_energies_and_weights() for be, f in zip(be_n, f_n): if f > 0.1 and be < BE_HOMO: BE_HOMO = be equal(BE_HOMO, VDE) lr = LrTDDFT(calc_plus, xc=xc) out = 'lrpes.dat' pes = TDDFTPES(calc, lr) pes.save_folded_pes(filename=out, folding='Gauss') pes.save_folded_pes(filename=None, folding=None) energy_tolerance = 0.0001 niter_tolerance = 1 equal(e_H2, -3.90059, energy_tolerance) equal(e_H2_plus, 10.5659703, energy_tolerance) # io out = 'lrpes.dat.gz' lr.write(out) lr = LrTDDFT(out) lr.set_calculator(calc_plus) pes = TDDFTPES(calc, lr) pes.save_folded_pes(filename=None, folding=None)
el = obj(calc, energy_range=8, txt=txt) if hasattr(obj, 'diagonalize'): el.diagonalize() # print "*************** obj, len(obj)", obj.__name__, len(el) assert len(el) == 4 el = obj(calc, energy_range=11.5, txt=txt) # print "*************** obj, len(obj)", obj.__name__, len(el) if hasattr(obj, 'diagonalize'): el.diagonalize() assert len(el) == 18 if hasattr(obj, 'diagonalize'): el.diagonalize(energy_range=8) assert len(el) == 4 lr = LrTDDFT(calc, nspins=2) lr.write('lrtddft3.dat.gz') lr.diagonalize() world.barrier() # This is done to test if writing and reading again yields the same result lr2 = LrTDDFT('lrtddft3.dat.gz') lr2.diagonalize() # Unfortunately not all of the lrtddft code is parallel if rank == 0: Epeak = 19.5# The peak we want to investigate (this is alone) Elist = np.asarray([lrsingle.get_energy() * Hartree for lrsingle in lr]) n = np.argmin(np.abs(Elist - Epeak)) # Index of the peak E = lr[n].get_energy() * Hartree
def get_paw(): """Return calculator object.""" c = {'energy': 0.05, 'eigenstates': 0.05, 'density': 0.05} return GPAW(convergence=c, eigensolver=RMMDIIS(), nbands=3, xc='PBE', # experimental={'niter_fixdensity': 2}, parallel={'domain': world.size}, h=0.35, occupations=FermiDirac(width=0.0, fixmagmom=True)) calc_plus = get_paw() calc_plus.set(txt='Be_plus_LCY_PBE_083.log', charge=1) o_plus.set_calculator(calc_plus) e_o_plus = o_plus.get_potential_energy() calc_plus.set(xc='LCY-PBE:omega=0.83:unocc=True', experimental={'niter_fixdensity': 2}) e_o_plus = o_plus.get_potential_energy() lr = LrTDDFT(calc_plus, txt='LCY_TDDFT_Be.log', istart=0, jend=1) equal(lr.xc.omega, 0.83) lr.write('LCY_TDDFT_Be.ex.gz') e_ion = 9.3 ip_i = 13.36 # reading is problematic with EXX on more than one core if world.rank == 0: lr2 = LrTDDFT('LCY_TDDFT_Be.ex.gz') lr2.diagonalize() equal(lr2.xc.omega, 0.83) ion_i = lr2[0].get_energy() * Hartree + e_ion equal(ion_i, ip_i, 0.3)