def calc_energy(formula, a=8.0): mol = molecule(formula) if len(mol) > 1: hund = False # an atom else: hund = True # molecule mol.set_cell((a, a, a)) mol.center() mol.set_pbc((True, True, True)) calc = GPAW(mode=PW(), xc="PBE", kpts={"density": 2.5}, hund=hund, txt="{0}.out".format(mol.get_chemical_formula())) mol.set_calculator(calc) E = mol.get_potential_energy() return E
def main(uid): print("Solving ID", uid) db = connect(DB_NAME) row = db.get(id=uid) atoms = row.toatoms() calc = GPAW(mode=PW(600), xc="PBE", nbands=-150, kpts={ 'density': 5.4, 'even': True }) atoms.set_calculator(calc) relaxer = BFGS(atoms, logfile="bfgs{}.log".format(uid)) relaxer.run(fmax=0.025) db.write(atoms, project=row.project, group=row.group)
def run_if_interactive(self): if self.structure.calc is None: kpoints = self.input['kpoints'] if isinstance(kpoints, str): kpoints = self.input['kpoints'].replace('[', '').replace( ']', '').split() self._create_working_directory() calc = GPAW( mode=PW(float(self.input['encut'])), xc=self.input['potential'], occupations=MethfesselPaxton(width=float(self.input['sigma'])), kpts=kpoints, txt=self.working_directory + '/' + self.job_name + '.txt') self.structure.set_calculator(calc) self.status.running = True self.structure.calc.calculate(self.structure) self.interactive_collect()
def get_hydrogen_chain_dielectric_function(NH, NK): a = Atoms('H', cell=[1, 1, 1], pbc=True) a.center() a = a.repeat((1, 1, NH)) a.calc = GPAW(mode=PW(200, force_complex_dtype=True), kpts={'size': (1, 1, NK), 'gamma': True}, parallel={'band': 1}, gpts=(10, 10, 10 * NH)) a.get_potential_energy() a.calc.diagonalize_full_hamiltonian(nbands=2 * NH) a.calc.write('H_chain.gpw', 'all') DF = DielectricFunction('H_chain.gpw', ecut=1e-3, hilbert=False, omega2=np.inf, intraband=False) eps_NLF, eps_LF = DF.get_dielectric_function(direction='z') omega_w = DF.get_frequencies() return omega_w, eps_LF
def calculate(aug): atoms.calc = GPAW(mode=PW(ecut), xc=xc, txt='gpaw.{}.aug{}.txt'.format(xc, aug), parallel={'augment_grids': aug}, kpts={'size': kpoints}, occupations=FermiDirac(width=0.1)) def stopcalc(): atoms.calc.scf.converged = True atoms.calc.attach(stopcalc, 4) e = atoms.get_potential_energy() f = atoms.get_forces() s = atoms.get_stress() return e, f, s
def main(uid): print("Solving ID", uid) db = connect(DB_NAME) row = db.get(id=uid) group = row.group atoms = row.toatoms() calc = GPAW(mode=PW(600), xc="PBE", nbands="150%", kpts={ 'density': 5.4, 'even': True }) atoms.set_calculator(calc) atoms.get_forces() db.write(atoms, group=group, struct_type="final")
def simulate_surface_Al(self, miller_index, energy_cutoff, n_k_points): ''' Function that adds surfaces to the aluminum nano particle ''' mixer = Mixer(beta=0.1, nmaxold=5, weight=50.0) # Recommended values for small systems # Initialize new calculator that only considers k-space in xy-plane, # since we're only looking at the surface calc = GPAW(mode=PW(energy_cutoff), # use the LCAO basis mode h=0.18, # grid spacing xc='PBE', # XC-functional mixer=mixer, kpts=(n_k_points, n_k_points, 1), # k-point grid txt='simulate_surface_Al_' + miller_index + 'GPAW.txt') # name of GPAW output text file self.get_surface_object(miller_index).set_calculator(calc) # Calc pot. energy of FCC surface_energy = self.surfaces[miller_index].get_potential_energy() self.surfaces[miller_index]['energy'] = surface_energy return surface_energy
def run_if_interactive(self): if self.structure.calc is None: kpoints = self.input["kpoints"] if isinstance(kpoints, str): kpoints = (self.input["kpoints"].replace("[", "").replace( "]", "").split()) self._create_working_directory() calc = GPAW( mode=PW(float(self.input["encut"])), xc=self.input["potential"], occupations=MethfesselPaxton(width=float(self.input["sigma"])), kpts=kpoints, txt=self.working_directory + "/" + self.job_name + ".txt", ) self.structure.set_calculator(calc) self.status.running = True self.structure.calc.calculate(self.structure) self.interactive_collect()
def test_dft(): atoms = read('data/graphene.traj') calc = GPAW(mode=PW(400), h=.1, txt=None, kpts=(4, 2, 2)) atoms.set_calculator(calc) atoms.get_potential_energy() potential_dft = GPAWPotential(calc, sampling=.05).build() potential_iam = Potential(atoms, sampling=.05).build() projected_dft = potential_dft.array.sum(0) projected_dft -= projected_dft.min() projected_iam = potential_iam.array.sum(0) projected_iam -= projected_iam.min() rel_diff = (projected_iam - projected_dft) / (projected_iam + 1e-16) * 100 rel_diff[projected_iam < 10] = np.nan assert np.round(np.nanmax(rel_diff) / 10, 0) * 10 == 40
def simulate_bulk_Al(self, energy_cutoff, n_k_points): ''' Function that calculates volume and energy for bulk aluminium. The function uses GPAW with a plane wave basis set and the PBE exchange correlation. ''' # # # Create Al bulk and initialize calculator parameters # # # mixer = Mixer(beta=0.1, nmaxold=5, weight=50.0) # Recommended values for small systems calc = GPAW(mode=PW(energy_cutoff), # use the LCAO basis mode h=0.18, # grid spacing, recommended value in this course xc='PBE', # Exchange-correlation functional mixer=mixer, # k-point grid - LOOP OVER LATER TO CHECK "CONVERGENCE" kpts=(n_k_points, n_k_points, n_k_points), txt='simulate_bulk_Al_GPAW.txt') # name of GPAW output text file self.bulk_Al['object'].set_calculator(calc) self.bulk_Al['volume'] = self.bulk_Al['object'].get_volume() self.bulk_Al['energy'] = self.bulk_Al['object'].get_potential_energy() return self.bulk_Al['energy']
def makeGPAWcalc(p): from gpaw import GPAW, PW, Davidson, Mixer, MixerSum, FermiDirac return GPAW( mode=PW(p['pw']), xc=p['xc'], kpts=kpt, spinpol=spinpol, convergence={'energy': p['econv']} #eV/electron , mixer=((MixerSum(beta=p['mixing'], nmaxold=p['nmix'], weight=100)) if spinpol else (Mixer(beta=p['mixing'], nmaxold=p['nmix'], weight=100))), maxiter=p['maxstep'], nbands=p['nbands'], occupations=FermiDirac(p['sigma']), setups=p['psp'], eigensolver=Davidson(5), poissonsolver=None, txt='log', symmetry={'do_not_symmetrize_the_density': True})
def aual100(site, height, calc=None): slab = fcc100('Al', size=(2, 2, 2)) slab.center(axis=2, vacuum=3.0) add_adsorbate(slab, 'Au', height, site) mask = [atom.symbol == 'Al' for atom in slab] fixlayer = FixAtoms(mask=mask) slab.set_constraint(fixlayer) if calc is None: calc = GPAW(mode=PW(200), kpts=(2, 2, 1), xc='PBE', txt=site + '.txt', eigensolver='rmm-diis', nbands=40) slab.set_calculator(calc) qn = QuasiNewton(slab, trajectory=site + calc.name + '.traj') qn.run(fmax=0.05) if isinstance(calc, GPAW): calc.write(site + '.gpw') return slab.get_potential_energy()
def convergeK(atoms, tol=1e-4, kstart=4): # Converge total energy by increasing k-space sampling until total energy changes by # <10^-4 eV. # DBs convDB = connect('./bulk.db', append=False) # DB for electronic spectrum k = kstart Etot_old = 1 Etot_new = 2 E = [] ks = [] i = 1 while np.abs(Etot_new - Etot_old) > tol: start = time.time() Etot_old = Etot_new # if world.rank == 0: print(f'---- Iteration: {i} ---- k={k} ----') calc = GPAW( mode=PW(200), # cutoff - lower for computational efficiency kpts=(k, k, k), # k-points txt=f'./gpaw-out/k={k}.txt' # output file ) atoms.set_calculator(calc) Etot_new = atoms.get_potential_energy() # Calculates the total DFT energy of the bulk material end = time.time() # if world.rank == 0: print(f'Energy: {Etot_new:.4f} eV ---- Time: {(end-start):.2f} s') E.append(Etot_new) ks.append(k) k += 4 i += 1 # Save calculator state and write to DB # if world.rank == 0: convDB.write(atoms, data={'energies': E, 'ks': ks}) calc.write('kConverge.gpw') print('Written to DB') return k, calc
def run_dft(uid, density, relax): db_name = "/home/davidkl/GPAWTutorial/AlMgSiMC/surface_tension_mgsi.db" db = connect(db_name) atoms = db.get(id=uid) kpts = {"even": True, "density": density} calc = GPAW(PW(600), kpts=kpts, xc="PBE", nbands="200%") atoms.set_calculator(calc) if relax: relaxer = PreconFIRE(atoms, logfile="logfile{}.log".format(uid)) relaxer.attach(calc.write, 1, "backup{}.gpw".format(backup)) traj = Trajectory(atoms, "trajectory{}.traj".format(uid)) relaxer.attach(traj) relaxer.run(fmax=0.025, smax=0.003) db.write(atoms, init_id=uid, runtype="geometry_opt") else: energy = atoms.get_potential_energy() init_id = db.get(id=uid).get("init_id", -1) db.write(atoms, init_id=init_id)
def slab(self, n, fd): a0 = self.reference['fcc']['a'] atoms = fcc111(self.symbol, (1, 1, 7), a0, vacuum=3.5) assert not atoms.pbc[2] M = 333 if 58 <= self.Z <= 70 or 90 <= self.Z <= 102: M = 1333 mixer = {'mixer': Mixer(0.001, 3, 100)} else: mixer = {} atoms.calc = GPAW(mode=PW(self.ecut1), kpts={ 'density': 2.0, 'even': True }, xc='PBE', setups='ga' + str(n), maxiter=M, txt=fd, **mixer) atoms.get_potential_energy() itrs = atoms.calc.get_number_of_iterations() return itrs
def calculate(d, k): label = 'gpaw.{xc}.domain{d}.kpt{k}'.format(xc=xc, d=d, k=k) atoms.calc = GPAW(mode=PW(ecut), xc=xc, txt=label + '.txt', parallel={ 'domain': d, 'kpt': k }, kpts={'size': kpoints}, occupations=FermiDirac(width=0.1)) def stopcalc(): atoms.calc.scf.converged = True atoms.calc.attach(stopcalc, 4) e = atoms.get_potential_energy() f = atoms.get_forces() s = atoms.get_stress() atoms.calc.write(label + '.gpw', mode='all') GPAW(label + '.gpw', txt=None) return e, f, s
def run_ground_state(ground_state_file): graphene = make_graphene_cell() # First step: find the ground-state charge density. # Use plane-wave basis with 600 eV cutoff energy for wavefunction variation in the # plane of the graphene sheet. https://wiki.fysik.dtu.dk/gpaw/setups/C.html calc = GPAW(mode=PW(600), xc='PBE', # 0.2 Angstrom real-space basis grid spacing perpendicular to the plane h=0.2, # Sample the Brillouin zone with 25 k-points in each reciprocal lattice direction # (only the in-plane directions). For the triangular lattice, we need to # be sure to include the Gamma point k = (0, 0, 0) to have the k-point sampling # match the symmetry of the Brillouin zone. kpts={'size': (25, 25, 1), 'gamma': True}, occupations=FermiDirac(0.01), random=True, txt="graphene_gs.txt") graphene.calc = calc graphene.get_potential_energy() calc.write(ground_state_file, 'all')
def rocksalt(self, n, fd): ref = self.reference['rocksalt'] a0r = ref['a'] sc = min(0.8, 2 * (self.rc + self.rco) / a0r) sc = min((abs(s - sc), s) for s in ref if s != 'a')[1] maxiter = 0 energies = [] M = 200 mixer = {} if 58 <= self.Z <= 70 or 90 <= self.Z <= 102: M = 999 mixer = {'mixer': Mixer(0.01, 5)} for s in [sc, 0.9, 0.95, 1.0, 1.05]: atoms = bulk(self.symbol + 'O', 'rocksalt', a0r * s) atoms.calc = GPAW(mode=PW(self.ecut2), kpts={ 'density': 4.0, 'even': True }, xc='PBE', setups={self.symbol: 'ga' + str(n)}, maxiter=M, txt=fd, **mixer) e = atoms.get_potential_energy() maxiter = max(maxiter, atoms.calc.get_number_of_iterations()) energies.append(e) return { 'c90': energies[1] - energies[3], 'c80': energies[0] - energies[3], 'c90ref': ref[0.9] - ref[1.0], 'c80ref': ref[sc] - ref[1.0], 'a0': fit([ref[s] for s in [0.95, 1.0, 1.05]]) * 0.05 * a0r, 'a': fit(energies[2:]) * 0.05 * a0r, 'maxiter': maxiter }
def run_gpaw(configuration, max_force): """Run a periodic DFT calculation using GPAW. Will set configuration.energy and configuration.forces as their DFT calculated values at the 400eV/PBE level of theory -------------------------------------------------------------------------- :param configuration: (gaptrain.configurations.Configuration) :param max_force: (float) or None """ from gpaw import GPAW, PW from ase.optimize import BFGS if ('GPAW_SETUP_PATH' not in os.environ.keys() or os.environ['GPAW_SETUP_PATH'] == ''): raise AssertionError('$GPAW_SETUP_PATH needs to be set') ase_atoms = configuration.ase_atoms() dft = GPAW(mode=PW(400), basis='dzp', charge=configuration.charge, xc='PBE', txt=None) ase_atoms.set_calculator(dft) if max_force is not None: minimisation = BFGS(ase_atoms) minimisation.run(fmax=float(max_force)) set_configuration_atoms_from_ase(configuration, ase_atoms) configuration.energy = ase_atoms.get_potential_energy() configuration.forces = ase_atoms.get_forces() return configuration
def gpawCalc(self, xc, spinpol): from gpaw import GPAW, PW, Davidson, Mixer, MixerSum, FermiDirac return GPAW( mode=PW(self.pw) #eV , xc=xc, kpts=self.kpt, spinpol=spinpol, convergence={'energy': self.econv} #eV/electron , mixer=((MixerSum(beta=self.mixing, nmaxold=self.nmix, weight=100)) if spinpol else (Mixer(beta=self.mixing, nmaxold=self.nmix, weight=100))), maxiter=self.maxstep, nbands=-1 * self.nbands, occupations=FermiDirac(self.sigma), setups='sg15', eigensolver=Davidson(5), poissonsolver= None # {'dipolelayer': 'xy'} if isinstance(self,SurfaceJob) else None , txt='%d_%s.txt' % (self.pw, xc), symmetry={'do_not_symmetrize_the_density': True}) #ERROR IN LI bcc 111 surface
def calc(fname="POSCAR_li_p"): vol = [] e = [] for x in np.linspace(.95, 1.05, 6): parprint(f"GGA {fname} @ {x}") parprint("="*50) a = read(fname) pos = a.get_scaled_positions() a.set_cell(a.cell*x) a.set_scaled_positions(pos) calc = GPAW(mode=PW(800), xc='PBE', kpts=(15, 15, 15), basis='dzp', txt=f'pn21-{x}.txt') a.calc = calc e.append(a.get_potential_energy()) vol.append(a.get_volume()) data = [vol, e] with open(f'data_{fname}.pickle', 'wb') as handle: pickle.dump(data, handle, protocol=pickle.HIGHEST_PROTOCOL) parprint("done") parprint("-"*50)
from gpaw.test import equal name = 'quartz' # no. 152 - trigonal a = 5.032090 c = a * 1.0968533 p0 = (0.4778763, 0.0, 1. / 3.) p1 = (0.4153076, 0.2531340, 0.2029893) atoms = crystal(['Si', 'O'], basis=[p0, p1], spacegroup=152, cellpar=[a, a, c, 90, 90, 120]) ## with fractional translations calc = GPAW(mode=PW(), xc='LDA', kpts=(3, 3, 3), nbands=42, symmetry={'symmorphic': False}, gpts=(20, 20, 24), eigensolver='rmm-diis') atoms.set_calculator(calc) energy_fractrans = atoms.get_potential_energy() assert(len(calc.wfs.kd.ibzk_kc) == 7) assert(len(calc.wfs.kd.symmetry.op_scc) == 6) ## without fractional translations calc = GPAW(mode=PW(),
# Set calculator # loop a number of times to capture if minimization stops with high force # due to the VariansBreak calls niter = 0 # If the structure is already fully relaxed just return it traj = Trajectory(label + '_lcao.traj', 'w', structure) while (structure.get_forces()** 2).sum(axis=1).max()**0.5 > forcemax and niter < niter_max: dyn = BFGS(structure, logfile=label + '.log') vb = VariansBreak(structure, dyn, min_stdev=0.01, N=15) dyn.attach(traj) dyn.attach(vb) dyn.run(fmax=forcemax, steps=steps) niter += 1 #print('relaxgpaw over',flush=True) return structure calc = GPAW(mode=PW(500), xc='PBE', basis='dzp', kpts=(3, 3, 1)) traj = Trajectory('V2O5_H2OTiO2_101_DFTrelaxed.traj', 'w') name = 'V2O5_H2OTiO2_101surface_gm' data = read('BE_V2O5_H2O_TiO2_101_I8.traj@:') for i in range(0, len(data)): name = 'V2O5H2OTiO2_101surface_isomer_{}'.format(i) a = data[i] a.set_calculator(calc) a_relaxed = relaxGPAW(a, name, forcemax=0.01, niter_max=2, steps=100) traj.write(a_relaxed)
print("path = ", spath) nkpts = elem_list[4] print("kpts = ", nkpts) kpts = ast.literal_eval(nkpts) La = float(elem_list[5]) print("lattice constant a = ", La) Lb = float(elem_list[6]) print("lattice constant b = ", Lb) Lc = float(elem_list[7]) print("lattice constant c = ", Lc) Lalpha = float(elem_list[8]) print("alpha angle = ", Lalpha) # First perform a regular SCF run calc = GPAW( mode=PW(400), maxiter=1500, spinpol=True, kpts=kpts, xc=xc, txt='-', occupations=FermiDirac(0.02), mixer=Mixer(0.01, 11, 100.0), ) atoms = bulk(element, struct, a=La, b=Lb, c=Lc, alpha=Lalpha) # sc,fcc,bcc,tetragonal,bct,hcp,rhmbohedral,orthorhombic # mlc, diamond,zincblende,rocksalt,cesiumchloride, fluorite, wurtzite atoms.set_calculator(calc) atoms.get_potential_energy()
kpts = 3 nbands = 8 # Part 2: optical transitions calculation response = 'density' spins = 'all' q_c = [0., 0., 0.] bzk_kc = np.array([[0., 0., 0.]]) # ------------------- Script ------------------- # # Part 1: ground state calculation a = 5.431 atoms = bulk('Si', 'diamond', a=a) calc = GPAW(mode=PW(pw), kpts=(kpts, kpts, kpts), nbands=nbands, convergence={'bands': -1}, xc='LDA', occupations=FermiDirac(0.001)) # use small FD smearing atoms.set_calculator(calc) atoms.get_potential_energy() # get ground state density calc.write('si.gpw', 'all') # write wavefunctions # Part 2: optical transition calculation pair, pd, domainarg_td = get_bz_transitions('si.gpw', q_c,
# Initial state: # 2x2-Al(001) surface with 1 layer and an # Au atom adsorbed in a hollow site: slab = fcc100('Al', size=(2, 2, 2)) slab.center(axis=2, vacuum=3.0) add_adsorbate(slab, 'Au', 1.6, 'hollow') # Make sure the structure is correct: view(slab) # Fix the Al atoms: mask = [atom.symbol == 'Al' for atom in slab] print(mask) fixlayer = FixAtoms(mask=mask) slab.set_constraint(fixlayer) # Use GPAW: calc = GPAW(mode=PW(200), kpts=(2, 2, 1), xc='PBE', txt='hollow.txt') slab.set_calculator(calc) qn = QuasiNewton(slab, trajectory='hollow.traj') # Find optimal height. The stopping criterion is: the force on the # Au atom should be less than 0.05 eV/Ang qn.run(fmax=0.05) calc.write('hollow.gpw') # Write gpw output after the minimization print('energy:', slab.get_potential_energy()) print('height:', slab.positions[-1, 2] - slab.positions[0, 2])
from gpaw.wavefunctions.pw import PW if rank != 0: sys.stdout = devnull assert size <= 4**3 # Ground state calculation t1 = time.time() a = 4.043 atoms = bulk('Al', 'fcc', a=a) atoms.center() calc = GPAW( mode=PW(200), kpts=(4, 4, 4), parallel={'band': 1}, idiotproof=False, # allow uneven distribution of k-points xc='LDA') atoms.set_calculator(calc) atoms.get_potential_energy() calc.write('Al', 'all') t2 = time.time() # Excited state calculation q = np.array([1 / 4., 0., 0.]) w = np.linspace(0, 24, 241) df = DielectricFunction(calc='Al',
from ase.build import bulk from gpaw import GPAW, PW from gpaw.xc.libvdwxc import vdw_df_cx # "Large" system: atoms = bulk('Cu').repeat((2, 2, 2)) calc = GPAW(mode=PW(600), kpts=(4, 4, 4), xc=vdw_df_cx(mode='pfft', pfft_grid=(2, 2)), parallel=dict(kpt=4, augment_grids=True)) atoms.set_calculator(calc) atoms.get_potential_energy()
from __future__ import print_function from ase import Atoms from gpaw import GPAW, PW from gpaw.mpi import rank, size, serial_comm from gpaw.xc.hybridg import HybridXC a = 2.0 li = Atoms('Li', cell=(a, a, a), pbc=1) for spinpol in [False, True]: for symm in [{}, 'off', {'time_reversal': False, 'point_group': False}]: if size == 8 and not spinpol and symm == {}: continue for qparallel in [False, True]: if rank == 0: print((spinpol, symm, qparallel)) li.calc = GPAW(mode=PW(300), kpts=(2, 3, 4), spinpol=spinpol, symmetry=symm, parallel={'band': 1}, txt=None, idiotproof=False) e = li.get_potential_energy() if qparallel: li.calc.write('li', mode='all') calc = GPAW('li', txt=None, communicator=serial_comm) else: calc = li.calc exx = HybridXC('EXX', logfilename=None, method='acdf') de = calc.get_xc_difference(exx) exx = HybridXC('EXX',
from ase import Atoms from gpaw import GPAW, PW, FermiDirac calc = GPAW(mode=PW(500), xc='PBE', h=0.10, occupations=FermiDirac(width=0.001), kpts={ 'size': (8, 8, 8), 'gamma': True }, parallel={ 'band': 1, 'domain': 1 }, txt='gs_Bi2Se3.txt') a = 4.138 c = 28.64 mu = 0.399 nu = 0.206 cell = [[-a / 2, -3**0.5 / 6 * a, c / 3], [a / 2, -3**0.5 / 6 * a, c / 3], [0.0, 3**0.5 / 3 * a, c / 3]] pos = [[mu, mu, mu], [-mu, -mu, -mu], [0.0, 0.0, 0.0], [nu, nu, nu], [-nu, -nu, -nu]] a = Atoms('Bi2Se3', cell=cell, scaled_positions=pos, pbc=True) a.set_calculator(calc) a.get_potential_energy() calc.write('gs_Bi2Se3.gpw')