def absorption_kick(self, kick_strength): self.tddft_init() self.timer.start('Kick') self.kick_strength = np.array(kick_strength, dtype=float) magnitude = np.sqrt(np.sum(self.kick_strength**2)) direction = self.kick_strength / magnitude self.log('---- Applying absorption kick') self.log('---- Magnitude: %.8f Hartree/Bohr' % magnitude) self.log('---- Direction: %.4f %.4f %.4f' % tuple(direction)) # Create hamiltonian object for absorption kick cef = ConstantElectricField(magnitude * Hartree / Bohr, direction) kick_hamiltonian = KickHamiltonian(self, cef) # Propagate kick self.propagator.kick(kick_hamiltonian, self.time) # Call observers after kick self.action = 'kick' self.call_observers(self.niter) self.niter += 1 self.timer.stop('Kick')
def add_efield(fname, efield=0): printit('Starting Efield calculation for efiled = {}'.format(efield)) atom, calc = restart('gs_' + fname + '.gpw') calc.set(txt='gs_efield_{}.txt'.format(efield)) calc.set(external=ConstantElectricField(efield, [0, 0, 1])) calc.get_potential_energy() calc.write('gs_' + fname + '_{}.gpw'.format(efield), mode='all') printit('Efield GS calculation done') gap, p1, p2 = get_gap(calc) printit("{} {} {} {}".format(efield, gap, p1, p2), fname="gaps.dat") printit("efield={} gap={}".format(efield, gap))
def efield(efield=0.05, n=30): printit('running GS calculation for {}'.format(efield)) fname = "sb_relaxed.cif" a = read(fname) atom = read(fname) wire = make_supercell(atom, [[n, 0, 0], [0, 1, 0], [ 0, 0, 1]], wrap=True, tol=1e-05) wire.center(vacuum=15, axis=0) a = wire.copy() if not os.path.isfile('gs_{}.gpw'.format(efield)): calc = GPAW( # mode='lcao', mode='fd', basis='szp(dzp)', # eigensolver='cg', #mixer=Mixer(beta=0.2, nmaxold=3, weight=70.0), xc='PBE', # poissonsolver=DipoleCorrection(PoissonSolver(relax='GS'), 2), mixer=Mixer(beta=0.06, nmaxold=5, weight=100.0), occupations=FermiDirac(width=0.1), kpts={'density': 4.5}, txt='gs_output_{}.txt'.format(efield), h=0.20, external=ConstantElectricField(efield, [0, 0, 1])) a.set_calculator(calc) a.get_potential_energy() calc.write('gs_{}.gpw'.format(efield)) calc = GPAW('gs_{}.gpw'.format(efield), nbands=-100, fixdensity=True, symmetry='off', kpts={'path': 'XGX', 'npoints': 100}, convergence={'bands': 'CBM+1'}, txt='gs_output_{}.txt'.format(efield)) calc.get_potential_energy() bs = calc.band_structure() bs.plot(filename='bandstructure_{}.png'.format( efield), show=False, emax=calc.get_fermi_level()+1, emin=calc.get_fermi_level()-1) bs.write('bs_{}.json'.format( efield)) try: gap, p1, p2 = get_gap(calc) printit("{} {} {} {}".format(efield, gap, p1, p2), fname="gaps.dat") except: None
def absorption_kick(self, kick_strength): self.tddft_init() self.timer.start('Kick') self.kick_strength = np.array(kick_strength, dtype=float) # magnitude magnitude = np.sqrt(np.sum(self.kick_strength**2)) # normalize direction = self.kick_strength / magnitude self.log('Applying absorption kick') self.log('Magnitude: %.8f hartree/bohr' % magnitude) self.log('Direction: %.4f %.4f %.4f' % tuple(direction)) # Create hamiltonian object for absorption kick cef = ConstantElectricField(magnitude * Hartree / Bohr, direction) kick_hamiltonian = KickHamiltonian(self, cef) for k, kpt in enumerate(self.wfs.kpt_u): Vkick_MM = self.wfs.eigensolver.calculate_hamiltonian_matrix( kick_hamiltonian, self.wfs, kpt, add_kinetic=False, root=-1) for i in range(10): self.propagate_wfs(kpt.C_nM, kpt.C_nM, kpt.S_MM, Vkick_MM, 0.1) self.timer.stop('Kick')
}, maxiter=1000, txt=txt) a.set_calculator(c) # Test 2 if test2: e = [] e1s = [] d = [] fields = np.linspace(-maxfield, maxfield, nfs) for field in fields: if rank == 0 and debug: print(field) c.set(external=ConstantElectricField(field), ) etot = a.get_potential_energy() e += [etot] ev0 = c.get_eigenvalues(0) ev1 = c.get_eigenvalues(1) e1s += [min(ev0[0], ev1[0])] dip = c.get_dipole_moment() d += [dip[2]] pol1, dummy = np.polyfit(fields, d, 1) pol2, dummy1, dummy2 = np.polyfit(fields, e1s, 2) if rank == 0 and debug: print('From shift in 1s-state at constant electric field:') print(' alpha = ', -pol2, ' A**2/eV') print(' alpha = ', -pol2 * to_au, ' Bohr**3')
"""A proton in an electric field.""" from ase import Atoms from ase.units import Hartree, Bohr from gpaw import GPAW from gpaw.external import ConstantElectricField h = Atoms('H') h.center(vacuum=2.5) h.calc = GPAW(external=ConstantElectricField(1.0), # 1 eV / Ang charge=1, txt='h.txt') e = h.get_potential_energy() f1 = h.get_forces()[0, 2] h[0].z += 0.001 de = h.get_potential_energy() - e f2 = -de / 0.001 print(f1, f2) assert abs(f1 - 1) < 1e-4 assert abs(f2 - 1) < 5e-3 # Check writing and reading: h.calc.write('h') vext = GPAW('h', txt=None).hamiltonian.vext assert abs(vext.field_v[2] - 1.0 * Bohr / Hartree) < 1e-13
def initialize(self, paw, min_occdiff=1e-3, only_ia=True): if self.has_initialized: return paw.initialize_positions() # paw.set_positions() if self.wfs.gd.pbc_c.any(): self.C0_dtype = complex else: self.C0_dtype = float # Take quantities self.fermilevel = paw.occupations.get_fermi_level() self.S_uMM = [] self.C0_unM = [] self.eig_un = [] self.occ_un = [] for kpt in self.wfs.kpt_u: S_MM = kpt.S_MM assert np.max(np.absolute(S_MM.imag)) == 0.0 S_MM = S_MM.real self.S_uMM.append(S_MM) C_nM = kpt.C_nM if self.C0_dtype == float: assert np.max(np.absolute(C_nM.imag)) == 0.0 C_nM = C_nM.real self.C0_unM.append(C_nM) self.eig_un.append(kpt.eps_n) self.occ_un.append(kpt.f_n) # TODO: do the rest of the function with K-points # Construct p = (i, a) pairs u = 0 Nn = self.wfs.bd.nbands eig_n = self.eig_un[u] occ_n = self.occ_un[u] self.only_ia = only_ia f_p = [] w_p = [] i_p = [] a_p = [] ia_p = [] i0 = 0 for i in range(i0, Nn): if only_ia: a0 = i + 1 else: a0 = 0 for a in range(a0, Nn): f = occ_n[i] - occ_n[a] if only_ia and f < min_occdiff: continue w = eig_n[a] - eig_n[i] f_p.append(f) w_p.append(w) i_p.append(i) a_p.append(a) ia_p.append((i, a)) f_p = np.array(f_p) w_p = np.array(w_p) i_p = np.array(i_p, dtype=int) a_p = np.array(a_p, dtype=int) ia_p = np.array(ia_p, dtype=int) # Sort according to energy difference p_s = np.argsort(w_p) f_p = f_p[p_s] w_p = w_p[p_s] i_p = i_p[p_s] a_p = a_p[p_s] ia_p = ia_p[p_s] Np = len(f_p) P_p = [] for p in range(Np): P = np.ravel_multi_index(ia_p[p], (Nn, Nn)) P_p.append(P) P_p = np.array(P_p) dm_vMM = [] for v in range(3): direction = np.zeros(3, dtype=float) direction[v] = 1.0 magnitude = 1.0 cef = ConstantElectricField(magnitude * Hartree / Bohr, direction) kick_hamiltonian = KickHamiltonian(paw, cef) dm_MM = self.wfs.eigensolver.calculate_hamiltonian_matrix( kick_hamiltonian, paw.wfs, self.wfs.kpt_u[u], add_kinetic=False, root=-1) tri2full(dm_MM) # TODO: do not use this dm_vMM.append(dm_MM) C0_nM = self.C0_unM[u] dm_vnn = [] for v in range(3): dm_vnn.append(np.dot(C0_nM.conj(), np.dot(dm_vMM[v], C0_nM.T))) dm_vnn = np.array(dm_vnn) dm_vP = dm_vnn.reshape(3, -1) dm_vp = dm_vP[:, P_p] self.w_p = w_p self.f_p = f_p self.ia_p = ia_p self.P_p = P_p self.dm_vp = dm_vp self.has_initialized = True
"""A proton in an electric field.""" from ase import Atoms from ase.units import Hartree, Bohr from gpaw import GPAW from gpaw.external import ConstantElectricField h = Atoms('H') h.center(vacuum=2.5) h.calc = GPAW( external=ConstantElectricField(1.0), # 1 V / Ang charge=1, txt='h.txt') e = h.get_potential_energy() f1 = h.get_forces()[0, 2] h[0].z += 0.001 de = h.get_potential_energy() - e f2 = -de / 0.001 print(f1, f2) assert abs(f1 - 1) < 1e-4 assert abs(f2 - 1) < 5e-3 # Check writing and reading: h.calc.write('h') vext = GPAW('h', txt=None).hamiltonian.vext assert abs(vext.field_v[2] - 1.0 * Bohr / Hartree) < 1e-13