def read(self, filename): self.lrtddft = LrTDDFT(filename + '/' + filename + '.lr.dat.gz') self.atoms, self.calculator = restart( filename + '/' + filename, communicator=self.world) E0 = self.calculator.get_potential_energy() f = open(filename + '/' + filename + '.exst', 'r') f.readline() self.d = f.readline().replace('\n', '').split()[1] indextype = f.readline().replace('\n', '').split()[1] if indextype == 'UnconstraintIndex': iex = int(f.readline().replace('\n', '').split()[1]) self.index = UnconstraintIndex(iex) else: direction = f.readline().replace('\n', '').split()[1] if direction in [str(0), str(1), str(2)]: direction = int(direction) else: direction = None val = f.readline().replace('\n', '').split() if indextype == 'MinimalOSIndex': self.index = MinimalOSIndex(float(val[1]), direction) else: emin = float(val[2]) emax = float(val[3].replace(']', '')) self.index = MaximalOSIndex([emin, emax], direction) index = self.index.apply(self.lrtddft) self.results['energy'] = E0 + self.lrtddft[index].energy * Hartree self.lrtddft.set_calculator(self.calculator)
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
def expand_raman_by_symmetry(cachepath, phonon, disp_filenames, get_polarizability, ex_kw, subtract_equilibrium_polarizability): if os.path.exists(cachepath): parprint(f'Found existing {cachepath}') return np.load(cachepath) world.barrier() parprint(f'Expanding raman data by symmetry... ({cachepath})') disp_phonopy_sites, disp_carts = get_phonopy_displacements(phonon) prim_symmetry = phonon.primitive_symmetry.get_symmetry_operations() lattice = phonon.primitive.get_cell()[...] carts = phonon.primitive.get_positions() oper_frac_rots = prim_symmetry['rotations'] oper_frac_trans = prim_symmetry['translations'] oper_cart_rots = np.array( [np.linalg.inv(lattice).T @ R @ lattice.T for R in oper_frac_rots]) oper_cart_trans = oper_frac_trans @ lattice oper_deperms = [] for cart_rot, cart_trans in zip(oper_cart_rots, oper_cart_trans): carts = phonon.primitive.get_positions() transformed_carts = carts @ cart_rot.T + cart_trans oper_deperms.append(get_deperm(carts, transformed_carts, lattice)) oper_deperms = np.array(oper_deperms) disp_tensors = np.array([ get_polarizability( LrTDDFT.read(disp_filenames['ex']['disp'].format(i), **ex_kw)) for i in range(len(disp_phonopy_sites)) ]) if subtract_equilibrium_polarizability: disp_tensors -= get_polarizability( LrTDDFT.read(disp_filenames['ex']['eq'], **ex_kw)) pol_derivs = symmetry.expand_derivs_by_symmetry( disp_phonopy_sites, disp_carts, disp_tensors, symmetry.Tensor2Callbacks(), oper_cart_rots, oper_deperms, ) pol_derivs = np.array( pol_derivs.tolist()) # (n,3) dtype=object --> (n,3,3,3) dtype=complex np.save(cachepath, pol_derivs) return pol_derivs
def show(c2): c2.calculate(H2) ov = Overlap(c1).pseudo(c2) parprint('wave function overlap (pseudo):\n', ov) ov = Overlap(c1).full(c2) parprint('wave function overlap (full):\n', ov) lr2 = LrTDDFT(c2) ovkss = lr1.kss.overlap(ov[0], lr2.kss) parprint('KSSingles overlap:\n', ovkss) ovlr = lr1.overlap(ov[0], lr2) parprint('LrTDDFT overlap:\n', ovlr)
#load=True if not io_only: R=0.7 # approx. experimental bond length a = 3.0 c = 4.0 H2 = Atoms([Atom('H', (a / 2, a / 2, (c - R) / 2)), Atom('H', (a / 2, a / 2, (c + R) / 2))], cell=(a, a, c)) calc = GPAW(xc='PBE', nbands=3, spinpol=False, txt=txt) H2.set_calculator(calc) H2.get_potential_energy() xc='LDA' # without spin lr = LrTDDFT(calc, xc=xc) lr.diagonalize() t1 = lr[0] # course grids for finegrid in [1,0]: lr = LrTDDFT(calc, xc=xc, finegrid=finegrid) lr.diagonalize() t3 = lr[0] print 'finegrid, t1, t3=', finegrid, t1 ,t3 equal(t1.get_energy(), t3.get_energy(), 5.e-4) # with spin lr_vspin = LrTDDFT(calc, xc=xc, nspins=2) singlet, triplet = lr_vspin.singlets_triplets()
class ExcitedState(GPAW): def __init__(self, lrtddft=None, index=0, d=0.001, txt=None, parallel=0, communicator=None, name=None, restart=None): """ExcitedState object. parallel: Can be used to parallelize the numerical force calculation over images. """ self.timer = Timer() self.atoms = None if isinstance(index, int): self.index = UnconstraintIndex(index) else: self.index = index self.results = {} self.results['forces'] = None self.results['energy'] = None if communicator is None: try: communicator = lrtddft.calculator.wfs.world except: communicator = mpi.world self.world = communicator if restart is not None: self.read(restart) if txt is None: self.txt = self.lrtddft.txt else: self.txt = convert_string_to_fd(txt, self.world) if lrtddft is not None: self.lrtddft = lrtddft self.calculator = self.lrtddft.calculator self.atoms = self.calculator.atoms self.parameters = self.calculator.parameters if txt is None: self.txt = self.lrtddft.txt else: self.txt = convert_string_to_fd(txt, self.world) self.d = d self.parallel = parallel self.name = name self.log = GPAWLogger(self.world) self.log.fd = self.txt self.reader = None self.calculator.log.fd = self.txt self.log('#', self.__class__.__name__, __version__) self.log('#', self.index) if name: self.log('name=' + name) self.log('# Force displacement:', self.d) self.log def __del__(self): self.timer.write(self.log.fd) def set(self, **kwargs): self.calculator.set(**kwargs) def set_positions(self, atoms): """Update the positions of the atoms.""" self.atoms = atoms.copy() self.results['forces'] = None self.results['energy'] = None def write(self, filename, mode=''): try: os.makedirs(filename) except OSError as exception: if exception.errno != errno.EEXIST: raise self.calculator.write(filename=filename + '/' + filename, mode=mode) self.lrtddft.write(filename=filename + '/' + filename + '.lr.dat.gz', fh=None) f = open(filename + '/' + filename + '.exst', 'w') f.write('# ' + self.__class__.__name__ + __version__ + '\n') f.write('Displacement: {0}'.format(self.d) + '\n') f.write('Index: ' + self.index.__class__.__name__ + '\n') for k, v in self.index.__dict__.items(): f.write('{0}, {1}'.format(k, v) + '\n') f.close() mpi.world.barrier() def read(self, filename): self.lrtddft = LrTDDFT(filename + '/' + filename + '.lr.dat.gz') self.atoms, self.calculator = restart( filename + '/' + filename, communicator=self.world) E0 = self.calculator.get_potential_energy() f = open(filename + '/' + filename + '.exst', 'r') f.readline() self.d = f.readline().replace('\n', '').split()[1] indextype = f.readline().replace('\n', '').split()[1] if indextype == 'UnconstraintIndex': iex = int(f.readline().replace('\n', '').split()[1]) self.index = UnconstraintIndex(iex) else: direction = f.readline().replace('\n', '').split()[1] if direction in [str(0), str(1), str(2)]: direction = int(direction) else: direction = None val = f.readline().replace('\n', '').split() if indextype == 'MinimalOSIndex': self.index = MinimalOSIndex(float(val[1]), direction) else: emin = float(val[2]) emax = float(val[3].replace(']', '')) self.index = MaximalOSIndex([emin, emax], direction) index = self.index.apply(self.lrtddft) self.results['energy'] = E0 + self.lrtddft[index].energy * Hartree self.lrtddft.set_calculator(self.calculator) def calculation_required(self, atoms, quantities): if len(quantities) == 0: return False if self.atoms is None: return True elif (len(atoms) != len(self.atoms) or (atoms.get_atomic_numbers() != self.atoms.get_atomic_numbers()).any() or (atoms.get_initial_magnetic_moments() != self.atoms.get_initial_magnetic_moments()).any() or (atoms.get_cell() != self.atoms.get_cell()).any() or (atoms.get_pbc() != self.atoms.get_pbc()).any()): return True elif (atoms.get_positions() != self.atoms.get_positions()).any(): return True for quantity in ['energy', 'forces']: if quantity in quantities: quantities.remove(quantity) if self.results[quantity] is None: return True return len(quantities) > 0 def check_state(self, atoms, tol=1e-15): system_changes = GPAW.check_state(self.calculator, atoms, tol) return system_changes def get_potential_energy(self, atoms=None, force_consistent=None): """Evaluate potential energy for the given excitation.""" if atoms is None: atoms = self.atoms if self.calculation_required(atoms, ['energy']): self.results['energy'] = self.calculate(atoms) return self.results['energy'] def calculate(self, atoms): """Evaluate your energy if needed.""" self.set_positions(atoms) self.calculator.calculate(atoms) E0 = self.calculator.get_potential_energy() atoms.set_calculator(self) if hasattr(self, 'density'): del(self.density) self.lrtddft.forced_update() self.lrtddft.diagonalize() index = self.index.apply(self.lrtddft) energy = E0 + self.lrtddft[index].energy * Hartree self.log('--------------------------') self.log('Excited state') self.log(self.index) self.log('Energy: {0}'.format(energy)) self.log() return energy def get_forces(self, atoms=None, save=False): """Get finite-difference forces If save = True, restartfiles for every displacement are given """ if atoms is None: atoms = self.atoms if self.calculation_required(atoms, ['forces']): atoms.set_calculator(self) # do the ground state calculation to set all # ranks to the same density to start with E0 = self.calculate(atoms) finite = FiniteDifference( atoms=atoms, propertyfunction=atoms.get_potential_energy, save=save, name="excited_state", ending='.gpw', d=self.d, parallel=self.parallel) F_av = finite.run() self.set_positions(atoms) self.results['energy'] = E0 self.results['forces'] = F_av if self.txt: self.log('Excited state forces in eV/Ang:') symbols = self.atoms.get_chemical_symbols() for a, symbol in enumerate(symbols): self.log(('%3d %-2s %10.5f %10.5f %10.5f' % ((a, symbol) + tuple(self.results['forces'][a])))) return self.results['forces'] def forces_indexn(self, index): """ If restartfiles are created from the force calculation, this function allows the calculation of forces for every excited state index. """ atoms = self.atoms def reforce(self, name): excalc = ExcitedState(index=index, restart=name) return excalc.get_potential_energy() fd = FiniteDifference( atoms=atoms, save=True, propertyfunction=self.atoms.get_potential_energy, name="excited_state", ending='.gpw', d=self.d, parallel=0) atoms.set_calculator(self) return fd.restart(reforce) def get_stress(self, atoms): """Return the stress for the current state of the Atoms.""" raise NotImplementedError def initialize_density(self, method='dipole'): if hasattr(self, 'density') and self.density.method == method: return gsdensity = self.calculator.density lr = self.lrtddft self.density = ExcitedStateDensity( gsdensity.gd, gsdensity.finegd, lr.kss.npspins, gsdensity.charge, method=method, redistributor=gsdensity.redistributor) index = self.index.apply(self.lrtddft) self.density.initialize(self.lrtddft, index) self.density.update(self.calculator.wfs) def get_pseudo_density(self, **kwargs): """Return pseudo-density array.""" method = kwargs.pop('method', 'dipole') self.initialize_density(method) return GPAW.get_pseudo_density(self, **kwargs) def get_all_electron_density(self, **kwargs): """Return all electron density array.""" method = kwargs.pop('method', 'dipole') self.initialize_density(method) return GPAW.get_all_electron_density(self, **kwargs)
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')
out = 'dospes.dat' pes = DOSPES(calc, calc_plus, shift=True) pes.save_folded_pes(filename=out, folding=None) 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)
box = 2 nbands = 4 txt = '-' txt = None np.set_printoptions(precision=3, suppress=True) H2 = Cluster(molecule('H2')) H2.minimal_box(box, h) c1 = GPAW(h=h, txt=txt, eigensolver='dav', nbands=nbands, convergence={'eigenstates': nbands}) c1.calculate(H2) lr1 = LrTDDFT(c1) parprint('sanity --------') ov = Overlap(c1).pseudo(c1) parprint('pseudo(normalized):\n', ov) ov = Overlap(c1).pseudo(c1, False) parprint('pseudo(not normalized):\n', ov) ov = Overlap(c1).full(c1) parprint('full:\n', ov) equal(ov[0], np.eye(ov[0].shape[0], dtype=ov.dtype), 1e-10) def show(c2): c2.calculate(H2) ov = Overlap(c1).pseudo(c2) parprint('wave function overlap (pseudo):\n', ov)
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')
# folder function for name in ['Gauss', 'Lorentz']: folder = Folder(width, name) x = [0, 2] y = [[2, 0, 1], [1, 1, 1]] xl, yl = folder.fold(x, y, dx=.7) # check first value if name == 'Lorentz': func = Lorentz(width) else: func = Gauss(width) yy = np.dot(np.array(y)[:, 0], func.get(xl[0] - np.array(x))) equal(yl[0, 0], yy, 1.e-15) # write spectrum from gpaw.lrtddft import LrTDDFT from gpaw.lrtddft.spectrum import spectrum fname = 'lr.dat.gz' if os.path.exists(fname): lr = LrTDDFT(fname) lr.diagonalize() spectrum(lr, 'spectrum.dat')
# External imports import helper as h from gpaw import GPAW from gpaw.lrtddft import LrTDDFT # Retrieve the calculator from task 1 lr = LrTDDFT('../task1/TDDFT_Task1.dat') # Dump the results from the calculation to file h.dump_data(lr, fpath='dumpTask1.npz') # Also generate the discrete spectrum from GPAW h.discrete_spectrum(lr, 'GPAW_discrete.dat')
calc = GPAW(xc='PBE', nbands=2, spinpol=False, txt=txt) H2.set_calculator(calc) H2.get_potential_energy() ## calc.write('H2.gpw', 'all') else: calc = GPAW('H2.gpw', txt=txt) #calc.initialize_wave_functions() #----------------------------------------------------------- # DFT only xc='LDA' # no spin lr = LrTDDFT(calc, xc=xc) lr.diagonalize() lr_ApmB = LrTDDFT(calc, xc=xc, force_ApmB=True) lr_ApmB.diagonalize() print 'lr=', lr print 'ApmB=', lr_ApmB equal(lr[0].get_energy(), lr_ApmB[0].get_energy(), 5.e-10) # with spin print '------ with spin' if not load: c_spin = GPAW(xc='PBE', nbands=2, spinpol=True, parallel={'domain': mpi.world.size}, txt=txt)
box = 5. # box dimension h = 0.25 # grid spacing width = 0.01 # Fermi width nbands = 6 # bands in GS calculation nconv = 4 # bands in GS calculation to converge R = 2.99 # starting distance iex = 1 # excited state index d = 0.01 # step for numerical force evaluation exc = 'LDA' # xc for the linear response TDDFT kernel s = Cluster([Atom('Na'), Atom('Na', [0, 0, R])]) s.minimal_box(box, h=h) c = GPAW(h=h, nbands=nbands, eigensolver='cg', occupations=FermiDirac(width=width), setups={'Na': '1'}, convergence={'bands':nconv}) c.calculate(s) lr = LrTDDFT(c, xc=exc, eps=0.1, jend=nconv-1) ex = ExcitedState(lr, iex, d=d) s.set_calculator(ex) ftraj='relax_ex' + str(iex) ftraj += '_box' + str(box) + '_h' + str(h) ftraj += '_d' + str(d) + '.traj' traj = io.PickleTrajectory(ftraj, 'w', s) dyn = optimize.FIRE(s) dyn.attach(traj.write) dyn.run(fmax=0.05)
from gpaw import GPAW from gpaw.cluster import Cluster from gpaw.analyse.overlap import Overlap import gpaw.solvation as solv from gpaw.lrtddft import LrTDDFT from gpaw.poisson import PoissonSolver """Check whether LrTDDFT in solvation works""" h = 0.4 box = 2 nbands = 2 txt = '-' txt = None H2 = Cluster(molecule('H2')) H2.minimal_box(box, h) c1 = GPAW(h=h, txt=None, nbands=nbands) c1.calculate(H2) c2 = solv.SolvationGPAW(h=h, txt=None, nbands=nbands + 1, **solv.get_HW14_water_kwargs()) c2.calculate(H2) for poiss in [None, PoissonSolver(nn=c2.hamiltonian.poisson.nn)]: lr = LrTDDFT(c2, poisson=poiss) print(lr) print(Overlap(c1).pseudo(c2))
# Built-in packages import time # GPAW from gpaw import GPAW from gpaw.lrtddft import LrTDDFT from gpaw.lrtddft import photoabsorption_spectrum print( f'------------ Extracting shortened photoabsorption spectrum ------------' ) start = time.time() # Import LrTDDFT results from Task 1 lr = LrTDDFT('../task1/TDDFT_Task1.dat') lr.diagonalize(energy_range=4) # Only include up to 4 eV # Generate spectrum and save it wd = 0.06 photoabsorption_spectrum(lr, f'spectrum_w{wd}.dat', width=wd) # Extract all information about all transitions print('** LrTDDFT.analyse() output **') lr.analyse() print('*******************************') end = time.time() print('-------- Photoabsorption spectrum extracted in: ' + f'{(end-start):.2f} s --------'.rjust(34))
H2.set_calculator(calc) e_H2 = H2.get_potential_energy() niter_H2 = calc.get_number_of_iterations() calc_plus = GPAW(gpts=(12, 12, 12), xc=xc, nbands=2, parallel={'domain': mpi.world.size}, spinpol=True, txt=txt) calc_plus.set(charge=+1) H2_plus.set_calculator(calc_plus) e_H2_plus = H2_plus.get_potential_energy() niter_H2_plus = calc.get_number_of_iterations() lr = LrTDDFT(calc_plus, xc=xc) pes = DOSPES(calc, calc_plus) pes.save_folded_pes(filename=txt, folding=None) pes.save_folded_pes(filename=None, folding=None) pes = TDDFTPES(calc, lr) pes.save_folded_pes(filename=txt, folding='Gauss') pes.save_folded_pes(filename=None, folding=None) energy_tolerance = 0.000008 niter_tolerance = 0 equal(e_H2, -3.90059, energy_tolerance) equal(niter_H2, 15, niter_tolerance) equal(e_H2_plus, 10.5659703, energy_tolerance) equal(niter_H2_plus, 15, niter_tolerance)
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')
#load=True if not io_only: R=0.7 # approx. experimental bond length a = 3.0 c = 4.0 H2 = Atoms([Atom('H', (a / 2, a / 2, (c - R) / 2)), Atom('H', (a / 2, a / 2, (c + R) / 2))], cell=(a, a, c)) calc = GPAW(xc='PBE', nbands=3, spinpol=False, txt=txt) H2.set_calculator(calc) H2.get_potential_energy() xc='LDA' # without spin lr = LrTDDFT(calc, xc=xc) lr.diagonalize() t1 = lr[0] lr_calc = lr ex = ExcitedState(lr, 0) den = ex.get_pseudo_density() * Bohr**3 # course grids for finegrid in [1,0]: lr = LrTDDFT(calc, xc=xc, finegrid=finegrid) lr.diagonalize() t3 = lr[0] parprint('finegrid, t1, t3=', finegrid, t1 ,t3) equal(t1.get_energy(), t3.get_energy(), 5.e-4) # with spin
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 import GPAW from ase import Atoms from gpaw.lrtddft import LrTDDFT molecule = Atoms('Na2', positions=((0.0, 0.0, 0.0), (3.12, 0.0, 0.0))) molecule.center(vacuum=6.0) calc = GPAW(xc='PBE') molecule.set_calculator(calc) molecule.get_potential_energy() lr = LrTDDFT(calc, xc='LDA', istart=0, jend=10, nspins=2) lr.write('Omega_Na2.gz')
calc = GPAW(xc='PBE', nbands=2, spinpol=False, txt=txt) H2.set_calculator(calc) H2.get_potential_energy() ## calc.write('H2.gpw', 'all') else: calc = GPAW('H2.gpw', txt=txt) #calc.initialize_wave_functions() #----------------------------------------------------------- # DFT only xc = 'LDA' # no spin lr = LrTDDFT(calc, xc=xc) lr.diagonalize() lr_ApmB = LrTDDFT(calc, xc=xc, force_ApmB=True) lr_ApmB.diagonalize() parprint('lr=', lr) parprint('ApmB=', lr_ApmB) equal(lr[0].get_energy(), lr_ApmB[0].get_energy(), 5.e-10) # with spin parprint('------ with spin') if not load: c_spin = GPAW(xc='PBE', nbands=2, spinpol=True,
txt = '-' txt = '/dev/null' R = 0.7 # approx. experimental bond length a = 3.0 c = 4.0 H2 = Atoms([ Atom('H', (a / 2, a / 2, (c - R) / 2)), Atom('H', (a / 2, a / 2, (c + R) / 2)) ], cell=(a, a, c)) calc = GPAW(xc='PBE', h=0.25, nbands=3, spinpol=False, txt=txt) H2.set_calculator(calc) xc = 'LDA' lr = LrTDDFT(calc, xc=xc) # excited state with forces accuracy = 0.015 exst = ExcitedState(lr, 0, d=0.01, parallel=2, txt=sys.stdout) t0 = time.time() parprint("########### first call to forces --> calculate") forces = exst.get_forces(H2) parprint("time used:", time.time() - t0) for c in range(2): equal(forces[0, c], 0.0, accuracy) equal(forces[1, c], 0.0, accuracy) equal(forces[0, 2] + forces[1, 2], 0.0, accuracy) parprint("########### second call to potential energy --> just return")
c = 5.0 H2 = Atoms([ Atom('H', (a / 2, a / 2, (c - R) / 2)), Atom('H', (a / 2, a / 2, (c + R) / 2)) ], cell=(a, a, c)) calc = GPAW(xc=xc, nbands=2, spinpol=False, eigensolver='rmm-diis', txt=txt) H2.set_calculator(calc) H2.get_potential_energy() calc.write('H2saved_wfs.gpw', 'all') calc.write('H2saved.gpw') wfs_error = calc.wfs.eigensolver.error #print "-> starting directly after a gs calculation" lr = LrTDDFT(calc, txt='-') lr.diagonalize() #print "-> reading gs with wfs" gs = GPAW('H2saved_wfs.gpw', txt=txt) # check that the wfs error is read correctly, # but take rounding errors into account assert (abs(calc.wfs.eigensolver.error / gs.wfs.eigensolver.error - 1) < 1e-8) lr1 = LrTDDFT(gs, xc=xc, txt='-') lr1.diagonalize() # check the oscillator strrength assert (abs(lr1[0].get_oscillator_strength()[0] / lr[0].get_oscillator_strength()[0] - 1) < 1e-10) #print "-> reading gs without wfs"
mode='RPA', coupling=True, q=np.array([0,0,0.0001]), optical_limit=True, ecut=50., nbands=8) bse.initialize() H_SS = bse.calculate() bse.diagonalize(H_SS) w = np.real(bse.w_S) * Hartree print np.shape(w) energies = np.sort(w)[len(w)/2:] print 'BSE:', energies if casida: from gpaw.lrtddft import LrTDDFT from gpaw.lrtddft import photoabsorption_spectrum calc = GPAW('Na2.gpw',txt=None) lr = LrTDDFT(calc, xc=None, istart=0, jend=7, nspins=1) lr.diagonalize() photoabsorption_spectrum(lr, 'Na2_spectrum.dat', width=0.05) energies_lrtddft = lr.get_energies() * Hartree print 'lrTDDFT:', energies_lrtddft if compare: assert (np.abs(energies - energies_lrtddft)).max() < 3*1e-3
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 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)
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)
from gpaw import GPAW from gpaw.lrtddft import LrTDDFT, photoabsorption_spectrum from gpaw.inducedfield.inducedfield_lrtddft import LrTDDFTInducedField # Load LrTDDFT object lr = LrTDDFT('na2_lr.dat.gz') # Calculate photoabsorption spectrum as usual folding = 'Gauss' width = 0.1 e_min = 0.0 e_max = 4.0 photoabsorption_spectrum(lr, 'na2_casida_spectrum.dat', folding=folding, width=width, e_min=e_min, e_max=e_max, delta_e=1e-2) # Load GPAW object calc = GPAW('na2_gs_casida.gpw') # Calculate induced field frequencies = [1.0, 2.08] # Frequencies of interest in eV folding = 'Gauss' # Folding function width = 0.1 # Line width for folding in eV kickdir = 0 # Kick field direction 0, 1, 2 for x, y, z ind = LrTDDFTInducedField(paw=calc, lr=lr, frequencies=frequencies,
parallel={'domain': mpi.size}, xc='PBE', txt='CO-m.txt', spinpol=True) m = atoms.copy() m.set_initial_magnetic_moments([-1,1]) m.set_calculator(m_c) m.get_potential_energy() d_c = GPAW(gpts=N_c, nbands=16, mixer=MixerDif(0.1, 5, weight=100.0), convergence={'bands':10}, parallel={'domain': mpi.size}, xc='PBE', txt='CO-d.txt', spinpol=True) d = atoms.copy() d.set_initial_magnetic_moments([-1,1]) d_c.set(charge=1) d.set_calculator(d_c) d.get_potential_energy() istart=0 # band index of the first occ. band to consider jend=15 # band index of the last unocc. band to consider d_lr = LrTDDFT(d_c, xc='PBE', nspins=2 , istart=istart, jend=jend) d_lr.diagonalize() pes = TDDFTPES(m_c, d_lr, d_c) pes.save_folded_pes('CO-td.dat', folding=None) pes = DOSPES(m_c, d_c) pes.save_folded_pes('CO-dos.dat', folding=None)
# selection using an energy range 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
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)
calc.write('Na2.gpw','all') if bse: bse = BSE('Na2.gpw',w=np.linspace(0,15,151), q=np.array([0,0,0.0001]),optical_limit=True,ecut=50., nbands=8) bse.initialize() bse.calculate() w = np.real(bse.w_S) * Hartree energies = np.sort(w[:,np.nonzero(w>0)[0]]) print energies if casida: from gpaw.lrtddft import LrTDDFT from gpaw.lrtddft import photoabsorption_spectrum calc = GPAW('Na2.gpw',txt=None) lr = LrTDDFT(calc, xc=None, istart=0, jend=7, nspins=1) lr.diagonalize() photoabsorption_spectrum(lr, 'Na2_spectrum.dat', width=0.05) energies_lrtddft = lr.get_energies() * Hartree print 'lrTDDFT:', energies_lrtddft if compare: assert (np.abs(energies - energies_lrtddft)).max() < 3*1e-3
parallel={'domain': mpi.size}, xc='PBE', txt='CO-m.txt', spinpol=True) m = atoms.copy() m.set_initial_magnetic_moments([-1,1]) m.set_calculator(m_c) m.get_potential_energy() d_c = GPAW(gpts=N_c, nbands=16, mixer=MixerDif(0.1, 5, weight=100.0), convergence={'bands':10}, parallel={'domain': mpi.size}, xc='PBE', txt='CO-d.txt', spinpol=True) d = atoms.copy() d.set_initial_magnetic_moments([-1,1]) d_c.set(charge=1) d.set_calculator(d_c) d.get_potential_energy() istart=0 # band index of the first occ. band to consider jend=15 # band index of the last unocc. band to consider d_lr = LrTDDFT(d_c, xc='PBE', nspins=2 , istart=istart, jend=jend) d_lr.diagonalize() pes = TDDFTPES(m_c, d_lr, d_c) pes.save_folded_pes('CO-td.dat', folding=None) pes = DOSPES(m_c, d_c, shift=True) pes.save_folded_pes('CO-dos.dat', folding=None)
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)
# selection using an energy range 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
R = 0.7 # approx. experimental bond length a = 4.0 c = 5.0 H2 = Atoms([Atom('H', (a / 2, a / 2, (c - R) / 2)), Atom('H', (a / 2, a / 2, (c + R) / 2))], cell=(a, a, c)) calc = GPAW(xc=xc, nbands=2, spinpol=False, eigensolver='rmm-diis', txt=txt) H2.set_calculator(calc) H2.get_potential_energy() calc.write('H2saved_wfs.gpw', 'all') calc.write('H2saved.gpw') wfs_error = calc.wfs.eigensolver.error #print "-> starting directly after a gs calculation" lr = LrTDDFT(calc, txt='-') lr.diagonalize() #print "-> reading gs with wfs" gs = GPAW('H2saved_wfs.gpw', txt=txt) # check that the wfs error is read correctly, # but take rounding errors into account assert( abs(calc.wfs.eigensolver.error/gs.wfs.eigensolver.error - 1) < 1e-8) lr1 = LrTDDFT(gs, xc=xc, txt='-') lr1.diagonalize() # check the oscillator strrength assert (abs(lr1[0].get_oscillator_strength()[0] / lr[0].get_oscillator_strength()[0] -1) < 1e-10) #print "-> reading gs without wfs"