def write_input(self, atoms, properties=None, system_changes=None): FileIOCalculator.write_input(self, atoms, properties, system_changes) struct = crys.atoms2struct(atoms) self.cell = common.str_arr(struct.cell) self.kpoints = pwscf.kpoints_str_pwin(kpts2mp(atoms, self.kpts)) if isinstance(self.pp, bytes): pseudos = [ "%s.%s" % (sym, self.pp) for sym in struct.symbols_unique ] else: assert len(self.pp) == struct.ntypat pseudos = [] for sym in struct.symbols_unique: for ppi in self.pp: if ppi.startswith(sym): pseudos.append(ppi) break assert len(pseudos) == struct.ntypat self.atspec = pwscf.atspec_str(symbols=struct.symbols_unique, masses=struct.mass_unique, pseudos=pseudos) self.atpos = pwscf.atpos_str(symbols=struct.symbols, coords=struct.coords_frac) self.natoms = struct.natoms self.ntyp = struct.ntypat if self.backup: for fn in [self.infile, self.outfile]: if os.path.exists(fn): common.backup(fn) common.file_write(self.infile, self.fill_infile_templ())
def write_input(self, atoms, properties=None, system_changes=None): FileIOCalculator.write_input(self, atoms, properties, system_changes) struct = crys.atoms2struct(atoms) self.cell = common.str_arr(struct.cell) self.kpoints = pwscf.kpoints_str_pwin(kpts2mp(atoms, self.kpts)) if isinstance(self.pp, types.StringType): pseudos = ["%s.%s" %(sym, self.pp) for sym in struct.symbols_unique] else: assert len(self.pp) == struct.ntypat pseudos = [] for sym in struct.symbols_unique: for ppi in self.pp: if ppi.startswith(sym): pseudos.append(ppi) break assert len(pseudos) == struct.ntypat self.atspec = pwscf.atspec_str(symbols=struct.symbols_unique, masses=struct.mass_unique, pseudos=pseudos) self.atpos = pwscf.atpos_str(symbols=struct.symbols, coords=struct.coords_frac) self.natoms = struct.natoms self.ntyp = struct.ntypat if self.backup: for fn in [self.infile, self.outfile]: if os.path.exists(fn): common.backup(fn) common.file_write(self.infile, self.fill_infile_templ())
def __init__(self, restart=None, ignore_bad_restart_file=False, label='dftb', atoms=None, kpts=None, **kwargs): """Construct a DFTB+ calculator. """ from ase.dft.kpoints import monkhorst_pack if 'DFTB_PREFIX' in os.environ: slako_dir = os.environ['DFTB_PREFIX'] else: slako_dir = './' self.default_parameters = dict( Hamiltonian_='DFTB', Driver_='ConjugateGradient', Driver_MaxForceComponent='1E-4', Driver_ConvergentForcesOnly='No', Driver_MaxSteps=0, Hamiltonian_SlaterKosterFiles_='Type2FileNames', Hamiltonian_SlaterKosterFiles_Prefix=slako_dir, Hamiltonian_SlaterKosterFiles_Separator='"-"', Hamiltonian_SlaterKosterFiles_Suffix='".skf"', Hamiltonian_SCC='No', Hamiltonian_Eigensolver='RelativelyRobust{}') FileIOCalculator.__init__(self, restart, ignore_bad_restart_file, label, atoms, **kwargs) self.kpts = kpts # kpoint stuff by ase if self.kpts != None: mpgrid = kpts2mp(atoms, self.kpts) mp = monkhorst_pack(mpgrid) initkey = 'Hamiltonian_KPointsAndWeights' self.parameters[initkey + '_'] = '' for i, imp in enumerate(mp): key = initkey + '_empty' + str(i) self.parameters[key] = str(mp[i]).strip('[]') + ' 1.0' #the input file written only once if restart == None: self.write_dftb_in() else: if os.path.exists(restart): os.system('cp ' + restart + ' dftb_in.hsd') if not os.path.exists('dftb_in.hsd'): raise IOError('No file "dftb_in.hsd", use restart=None') #indexes for the result file self.first_time = True self.index_energy = None self.index_force_begin = None self.index_force_end = None self.index_charge_begin = None self.index_charge_end = None
def write_control(self, atoms, filename): lim = '#' + '=' * 79 output = open(filename, 'w') output.write(lim + '\n') for line in [ 'FHI-aims file: ' + filename, 'Created using the Atomic Simulation Environment (ASE)', time.asctime(), '', 'List of parameters used to initialize the calculator:', ]: output.write('# ' + line + '\n') for p, v in self.parameters.items(): s = '# {} : {}\n'.format(p, v) output.write(s) output.write(lim + '\n') assert not ('kpts' in self.parameters and 'k_grid' in self.parameters) assert not ('smearing' in self.parameters and 'occupation_type' in self.parameters) for key, value in self.parameters.items(): if key == 'kpts': mp = kpts2mp(atoms, self.parameters.kpts) output.write('%-35s%d %d %d\n' % (('k_grid', ) + tuple(mp))) dk = 0.5 - 0.5 / np.array(mp) output.write('%-35s%f %f %f\n' % (('k_offset', ) + tuple(dk))) elif key == 'species_dir' or key == 'run_command': continue elif key == 'plus_u': continue elif key == 'smearing': name = self.parameters.smearing[0].lower() if name == 'fermi-dirac': name = 'fermi' width = self.parameters.smearing[1] output.write('%-35s%s %f' % ('occupation_type', name, width)) if name == 'methfessel-paxton': order = self.parameters.smearing[2] output.write(' %d' % order) output.write('\n' % order) elif key == 'output': for output_type in value: output.write('%-35s%s\n' % (key, output_type)) elif key == 'vdw_correction_hirshfeld' and value: output.write('%-35s\n' % key) elif key in bool_keys: output.write('%-35s.%s.\n' % (key, repr(bool(value)).lower())) elif isinstance(value, (tuple, list)): output.write('%-35s%s\n' % (key, ' '.join(str(x) for x in value))) elif isinstance(value, basestring): output.write('%-35s%s\n' % (key, value)) else: output.write('%-35s%r\n' % (key, value)) if self.cubes: self.cubes.write(output) output.write(lim + '\n\n') output.close()
def __init__(self, restart=None, ignore_bad_restart_file=False, label='dftb', atoms=None, kpts=None, **kwargs): """Construct a DFTB+ calculator. """ from ase.dft.kpoints import monkhorst_pack if 'DFTB_PREFIX' in os.environ: slako_dir = os.environ['DFTB_PREFIX'] else: slako_dir = './' self.default_parameters = dict( Hamiltonian_='DFTB', Driver_='ConjugateGradient', Driver_MaxForceComponent='1E-4', Driver_ConvergentForcesOnly = 'No', Driver_MaxSteps=0, Hamiltonian_SlaterKosterFiles_='Type2FileNames', Hamiltonian_SlaterKosterFiles_Prefix=slako_dir, Hamiltonian_SlaterKosterFiles_Separator='"-"', Hamiltonian_SlaterKosterFiles_Suffix='".skf"', Hamiltonian_SCC = 'No', Hamiltonian_Eigensolver = 'RelativelyRobust{}' ) FileIOCalculator.__init__(self, restart, ignore_bad_restart_file, label, atoms, **kwargs) self.kpts = kpts # kpoint stuff by ase if self.kpts != None: mpgrid = kpts2mp(atoms, self.kpts) mp = monkhorst_pack(mpgrid) initkey = 'Hamiltonian_KPointsAndWeights' self.parameters[initkey + '_'] = '' for i, imp in enumerate(mp): key = initkey + '_empty' + str(i) self.parameters[key] = str(mp[i]).strip('[]') + ' 1.0' #the input file written only once if restart == None: self.write_dftb_in() else: if os.path.exists(restart): os.system('cp ' + restart + ' dftb_in.hsd') if not os.path.exists('dftb_in.hsd'): raise IOError('No file "dftb_in.hsd", use restart=None') #indexes for the result file self.first_time = True self.index_energy = None self.index_force_begin = None self.index_force_end = None self.index_charge_begin = None self.index_charge_end = None
def write_control(self, atoms, filename): output = open(filename, 'w') for line in ['=====================================================', 'FHI-aims file: ' + filename, 'Created using the Atomic Simulation Environment (ASE)', '', 'List of parameters used to initialize the calculator:', '=====================================================']: output.write('#' + line + '\n') assert not ('kpts' in self.parameters and 'k_grid' in self.parameters) assert not ('smearing' in self.parameters and 'occupation_type' in self.parameters) for key, value in self.parameters.items(): if key == 'kpts': mp = kpts2mp(atoms, self.parameters.kpts) output.write('%-35s%d %d %d\n' % (('k_grid',) + tuple(mp))) dk = 0.5 - 0.5 / np.array(mp) output.write('%-35s%f %f %f\n' % (('k_offset',) + tuple(dk))) elif key == 'species_dir' or key == 'run_command': continue elif key == 'smearing': name = self.parameters.smearing[0].lower() if name == 'fermi-dirac': name = 'fermi' width = self.parameters.smearing[1] output.write('%-35s%s %f' % ('occupation_type', name, width)) if name == 'methfessel-paxton': order = self.parameters.smearing[2] output.write(' %d' % order) output.write('\n' % order) elif key == 'output': for output_type in value: output.write('%-35s%s\n' % (key, output_type)) elif key == 'vdw_correction_hirshfeld' and value: output.write('%-35s\n' % key) elif key in bool_keys: output.write('%-35s.%s.\n' % (key, repr(bool(value)).lower())) elif isinstance(value, (tuple, list)): output.write('%-35s%s\n' % (key, ' '.join(str(x) for x in value))) elif isinstance(value, str): output.write('%-35s%s\n' % (key, value)) else: output.write('%-35s%r\n' % (key, value)) if self.cubes: self.cubes.write(output) output.write( '#=======================================================\n\n') output.close()
def write_input(self, atoms, properties=None, system_changes=None): FileIOCalculator.write_input(self, atoms, properties, system_changes) self.initialize(atoms) self.parameters.write(os.path.join(self.directory, 'parameters.ase')) if 'xctype' in self.parameters: if 'xc' in self.parameters: raise RuntimeError("You can't use both 'xctype' and 'xc'!") if self.parameters.get('autokpt'): if 'kpts' in self.parameters: raise RuntimeError("You can't use both 'autokpt' and 'kpts'!") if 'ngridk' in self.parameters: raise RuntimeError("You can't use both 'autokpt' and 'ngridk'!") if 'ngridk' in self.parameters: if 'kpts' in self.parameters: raise RuntimeError("You can't use both 'ngridk' and 'kpts'!") if self.parameters.get('autoswidth'): if 'smearing' in self.parameters: raise RuntimeError("You can't use both 'autoswidth' and 'smearing'!") if 'swidth' in self.parameters: raise RuntimeError("You can't use both 'autoswidth' and 'swidth'!") fd = open(os.path.join(self.directory, 'elk.in'), 'w') # handle custom specifications of rmt # (absolute or relative to default) in Bohr # rmt = {'H': 0.7, 'O': -0.2, ...} if self.parameters.get('rmt', None) is not None: self.rmt = self.parameters['rmt'].copy() assert len(self.rmt.keys()) == len(list(set(self.rmt.keys()))), 'redundant rmt definitions' self.parameters.pop('rmt') # this is not an elk keyword! else: self.rmt = None inp = {} inp.update(self.parameters) if 'xc' in self.parameters: xctype = {'LDA': 3, # PW92 'PBE': 20, 'REVPBE': 21, 'PBESOL': 22, 'WC06': 26, 'AM05': 30}[self.parameters.xc] inp['xctype'] = xctype del inp['xc'] if 'kpts' in self.parameters: mp = kpts2mp(atoms, self.parameters.kpts) inp['ngridk'] = tuple(mp) vkloff = [] # is this below correct? for nk in mp: if nk % 2 == 0: # shift kpoint away from gamma point vkloff.append(0.5) else: vkloff.append(0) inp['vkloff'] = vkloff del inp['kpts'] if 'smearing' in self.parameters: name = self.parameters.smearing[0].lower() if name == 'methfessel-paxton': stype = self.parameters.smearing[2] else: stype = {'gaussian': 0, 'fermi-dirac': 3, }[name] inp['stype'] = stype inp['swidth'] = self.parameters.smearing[1] del inp['smearing'] # convert keys to ELK units for key, value in inp.items(): if key in elk_parameters: inp[key] /= elk_parameters[key] # write all keys for key, value in inp.items(): fd.write('%s\n' % key) if isinstance(value, bool): fd.write('.%s.\n\n' % ('false', 'true')[value]) elif isinstance(value, (int, float)): fd.write('%s\n\n' % value) else: fd.write('%s\n\n' % ' '.join([str(x) for x in value])) # cell fd.write('avec\n') for vec in atoms.cell: fd.write('%.14f %.14f %.14f\n' % tuple(vec / Bohr)) fd.write('\n') # atoms species = {} symbols = [] for a, (symbol, m) in enumerate( zip(atoms.get_chemical_symbols(), atoms.get_initial_magnetic_moments())): if symbol in species: species[symbol].append((a, m)) else: species[symbol] = [(a, m)] symbols.append(symbol) fd.write('atoms\n%d\n' % len(species)) #scaled = atoms.get_scaled_positions(wrap=False) scaled = np.linalg.solve(atoms.cell.T, atoms.positions.T).T for symbol in symbols: fd.write("'%s.in' : spfname\n" % symbol) fd.write('%d\n' % len(species[symbol])) for a, m in species[symbol]: fd.write('%.14f %.14f %.14f 0.0 0.0 %.14f\n' % (tuple(scaled[a])+ (m,))) # species species_path = self.parameters.get('species_dir') if species_path is None: species_path = os.environ.get('ELK_SPECIES_PATH') if species_path is None: raise RuntimeError( 'Missing species directory! Use species_dir ' + 'parameter or set $ELK_SPECIES_PATH environment variable.') # custom species definitions if self.rmt is not None: fd.write("\n") sfile = os.path.join(os.environ['ELK_SPECIES_PATH'], 'elk.in') assert os.path.exists(sfile) slines = open(sfile, 'r').readlines() # remove unused species for s in self.rmt.keys(): if s not in species.keys(): self.rmt.pop(s) # add undefined species with defaults for s in species.keys(): if s not in self.rmt.keys(): # use default rmt for undefined species self.rmt.update({s: 0.0}) # write custom species into elk.in skeys = list(set(self.rmt.keys())) # unique skeys.sort() for s in skeys: found = False for n, line in enumerate(slines): if line.find("'" + s + "'") > -1: begline = n - 1 for n, line in enumerate(slines[begline:]): if not line.strip(): # first empty line endline = n found = True break assert found fd.write("species\n") # set rmt on third line rmt = self.rmt[s] assert isinstance(rmt, (float,int)) if rmt <= 0.0: # relative # split needed because H is defined with comments newrmt = float(slines[begline + 3].split()[0].strip()) + rmt else: newrmt = rmt slines[begline + 3] = '%6s\n' % str(newrmt) for l in slines[begline: begline + endline]: fd.write('%s' % l) fd.write("\n") else: # use default species # if sppath is present in elk.in it overwrites species blocks! fd.write("sppath\n'%s'\n\n" % os.environ['ELK_SPECIES_PATH'])
def write_abinit_in(fd, atoms, param=None, species=None): import copy from ase.calculators.calculator import kpts2mp from ase.calculators.abinit import Abinit if param is None: param = {} _param = copy.deepcopy(Abinit.default_parameters) _param.update(param) param = _param if species is None: species = sorted(set(atoms.numbers)) inp = {} inp.update(param) for key in ['xc', 'smearing', 'kpts', 'pps', 'raw']: del inp[key] smearing = param.get('smearing') if 'tsmear' in param or 'occopt' in param: assert smearing is None if smearing is not None: inp['occopt'] = {'fermi-dirac': 3, 'gaussian': 7}[smearing[0].lower()] inp['tsmear'] = smearing[1] inp['natom'] = len(atoms) if 'nbands' in param: inp['nband'] = param['nbands'] del inp['nbands'] # ixc is set from paw/xml file. Ignore 'xc' setting then. if param.get('pps') not in ['pawxml']: if 'ixc' not in param: inp['ixc'] = { 'LDA': 7, 'PBE': 11, 'revPBE': 14, 'RPBE': 15, 'WC': 23 }[param['xc']] magmoms = atoms.get_initial_magnetic_moments() if magmoms.any(): inp['nsppol'] = 2 fd.write('spinat\n') for n, M in enumerate(magmoms): fd.write('%.14f %.14f %.14f\n' % (0, 0, M)) else: inp['nsppol'] = 1 if param['kpts'] is not None: mp = kpts2mp(atoms, param['kpts']) fd.write('kptopt 1\n') fd.write('ngkpt %d %d %d\n' % tuple(mp)) fd.write('nshiftk 1\n') fd.write('shiftk\n') fd.write('%.1f %.1f %.1f\n' % tuple((np.array(mp) + 1) % 2 * 0.5)) valid_lists = (list, np.ndarray) for key in sorted(inp): value = inp[key] unit = keys_with_units.get(key) if unit is not None: if 'fs**2' in unit: value /= fs**2 elif 'fs' in unit: value /= fs if isinstance(value, valid_lists): if isinstance(value[0], valid_lists): fd.write("{}\n".format(key)) for dim in value: write_list(fd, dim, unit) else: fd.write("{}\n".format(key)) write_list(fd, value, unit) else: if unit is None: fd.write("{} {}\n".format(key, value)) else: fd.write("{} {} {}\n".format(key, value, unit)) if param['raw'] is not None: if isinstance(param['raw'], str): raise TypeError('The raw parameter is a single string; expected ' 'a sequence of lines') for line in param['raw']: if isinstance(line, tuple): fd.write(' '.join(['%s' % x for x in line]) + '\n') else: fd.write('%s\n' % line) fd.write('#Definition of the unit cell\n') fd.write('acell\n') fd.write('%.14f %.14f %.14f Angstrom\n' % (1.0, 1.0, 1.0)) fd.write('rprim\n') if atoms.number_of_lattice_vectors != 3: raise RuntimeError('Abinit requires a 3D cell, but cell is {}'.format( atoms.cell)) for v in atoms.cell: fd.write('%.14f %.14f %.14f\n' % tuple(v)) fd.write('chkprim 0 # Allow non-primitive cells\n') fd.write('#Definition of the atom types\n') fd.write('ntypat %d\n' % (len(species))) fd.write('znucl {}\n'.format(' '.join(str(Z) for Z in species))) fd.write('#Enumerate different atomic species\n') fd.write('typat') fd.write('\n') types = [] for Z in atoms.numbers: for n, Zs in enumerate(species): if Z == Zs: types.append(n + 1) n_entries_int = 20 # integer entries per line for n, type in enumerate(types): fd.write(' %d' % (type)) if n > 1 and ((n % n_entries_int) == 1): fd.write('\n') fd.write('\n') fd.write('#Definition of the atoms\n') fd.write('xangst\n') for pos in atoms.positions: fd.write('%.14f %.14f %.14f\n' % tuple(pos)) fd.write('chkexit 1 # abinit.exit file in the running ' 'directory terminates after the current SCF\n')
label = 'rmt2.1' atomsrmt = atoms.copy() os.environ['ELK_SPECIES_PATH'] = ELK_SPECIES_PATH atomsrmt.calc = ELK(tasks=0, label=label, rmt=rmt) # minimal calc atomsrmt.get_potential_energy() del atomsrmt.calc del atomsrmt # hack ELK_SPECIES_PATH to use custom species os.environ['ELK_SPECIES_PATH'] = os.path.abspath(label) + '/' # run calculation calc = ELK(tasks=0, label=label, rgkmax=4.0, kpts=tuple(kpts2mp(atoms, 2.0, even=True))) atoms.set_calculator(calc) e1 = atoms.get_potential_energy() # test2 # generate species with custom rmt 2.1 rmt = {'Al': -0.1} label = 'rmt0.1m' atomsrmt = atoms.copy() os.environ['ELK_SPECIES_PATH'] = ELK_SPECIES_PATH atomsrmt.calc = ELK(tasks=0, label=label, rmt=rmt) # minimal calc atomsrmt.get_potential_energy() del atomsrmt.calc del atomsrmt
def write_control(self, atoms, filename): lim = '#' + '=' * 79 output = open(filename, 'w') output.write(lim + '\n') for line in [ 'FHI-aims file: ' + filename, 'Created using the Atomic Simulation Environment (ASE)', time.asctime(), '', 'List of parameters used to initialize the calculator:', ]: output.write('# ' + line + '\n') for p, v in self.parameters.items(): s = '# {} : {}\n'.format(p, v) output.write(s) output.write(lim + '\n') assert not ('kpts' in self.parameters and 'k_grid' in self.parameters) assert not ('smearing' in self.parameters and 'occupation_type' in self.parameters) # Sort the keywords for the control.in according to the # grouping-dictionary if (self.hvr_approach == 'CPA'): write_restart_args = ['restart_aims', 'restart_write_only'] if not any( [wra in self.parameters.keys() for wra in write_restart_args]): self.parameters['restart_write_only'] = 'wvfn.dat' for key, value in self.parameters.items(): if key == 'kpts': mp = kpts2mp(atoms, self.parameters.kpts) output.write('%-35s%d %d %d\n' % (('k_grid', ) + tuple(mp))) dk = 0.5 - 0.5 / np.array(mp) output.write('%-35s%f %f %f\n' % (('k_offset', ) + tuple(dk))) elif key == 'species_dir' or key == 'run_command': continue elif key == 'plus_u': continue elif key == 'smearing': name = self.parameters.smearing[0].lower() if name == 'fermi-dirac': name = 'fermi' width = self.parameters.smearing[1] output.write('%-35s%s %f' % ('occupation_type', name, width)) if name == 'methfessel-paxton': order = self.parameters.smearing[2] output.write(' %d' % order) output.write('\n' % order) elif key == 'output': if (self.hvr_approach == 'HA') and ('Hirshfeld' not in value): print("You forgot to add 'Hirshfeld' to output, mate.") print("Let me fix that for you...") value.append('Hirshfeld') elif (self.hvr_approach == 'CPA'): if ('h_s_matrices' not in value): print( "You forgot to add 'h_s_matrices' to output, mate." ) print("Let me fix that for you...") value.append('h_s_matrices') if np.any(self.atoms.pbc) and ('k_point_list' not in value): print( "You're using PBC and forgot to add 'k_point_list' to output." ) print("Let me fix that for you...") value.append('k_point_list') for output_type in value: output.write('%-35s%s\n' % (key, output_type)) elif key == 'vdw_correction_hirshfeld' and value: output.write('%-35s\n' % key) elif key == 'many_body_dispersion' and value: if value in [True, '.true.']: output.write('%-35s\n' % key) else: output.write('%-35s%s\n' % (key, value)) elif key in bool_keys: output.write('%-35s.%s.\n' % (key, repr(bool(value)).lower())) elif isinstance(value, (tuple, list)): output.write('%-35s%s\n' % (key, ' '.join(str(x) for x in value))) elif isinstance(value, basestring): output.write('%-35s%s\n' % (key, value)) else: output.write('%-35s%r\n' % (key, value)) if self.cubes: self.cubes.write(output) output.write(lim + '\n\n') output.close()
def __init__(self, restart=None, ignore_bad_restart_file=False, label='dftb', atoms=None, kpts=None, run_manyDftb_steps=False, **kwargs): """Construct a DFTB+ calculator. run_manyDftb_steps: Logical True: many steps are run by DFTB+, False:a single force&energy calculation at given positions --------- Additional object (to be set by function embed) pcpot: PointCharge object An external point charge potential (only in qmmm) """ from ase.dft.kpoints import monkhorst_pack if 'DFTB_PREFIX' in os.environ: slako_dir = os.environ['DFTB_PREFIX'] else: slako_dir = './' # to run Dftb as energy and force calculator use # Driver_MaxSteps=0, if run_manyDftb_steps: # minimisation of molecular dynamics is run by native DFTB+ self.default_parameters = dict( Hamiltonian_='DFTB', Hamiltonian_SlaterKosterFiles_='Type2FileNames', Hamiltonian_SlaterKosterFiles_Prefix=slako_dir, Hamiltonian_SlaterKosterFiles_Separator='"-"', Hamiltonian_SlaterKosterFiles_Suffix='".skf"', Hamiltonian_MaxAngularMomentum_='') else: # using ase to get forces and energy only # (single point calculation) self.default_parameters = dict( Hamiltonian_='DFTB', Driver_='ConjugateGradient', Driver_MaxForceComponent='1E-4', Driver_MaxSteps=0, Hamiltonian_SlaterKosterFiles_='Type2FileNames', Hamiltonian_SlaterKosterFiles_Prefix=slako_dir, Hamiltonian_SlaterKosterFiles_Separator='"-"', Hamiltonian_SlaterKosterFiles_Suffix='".skf"', Hamiltonian_MaxAngularMomentum_='') self.pcpot = None self.lines = None self.atoms = None self.atoms_input = None self.outfilename = 'dftb.out' FileIOCalculator.__init__(self, restart, ignore_bad_restart_file, label, atoms, **kwargs) self.kpts = kpts # kpoint stuff by ase if self.kpts is not None: mpgrid = kpts2mp(atoms, self.kpts) mp = monkhorst_pack(mpgrid) initkey = 'Hamiltonian_KPointsAndWeights' self.parameters[initkey + '_'] = '' for i, imp in enumerate(mp): key = initkey + '_empty' + str(i) self.parameters[key] = str(mp[i]).strip('[]') + ' 1.0'
def __init__(self, restart=None, ignore_bad_restart_file=False, label='dftb', atoms=None, kpts=None, **kwargs): """ Construct a DFTB+ calculator. """ from ase.dft.kpoints import monkhorst_pack from os.path import exists as pexists do_3rd_o = kwargs.get('Hamiltonian_ThirdOrder', 'No') do_3rd_f = kwargs.get('Hamiltonian_ThirdOrderFull', 'No') do_3rd_order = any( np.asarray([do_3rd_o.lower(), do_3rd_f.lower()]) == 'yes') default_beta_MBD = 0.89 if do_3rd_order else 0.95 default_sR_TS = 1.03 if do_3rd_order else 1.06 if 'DFTB_PREFIX' in os.environ: slako_dir = os.environ['DFTB_PREFIX'] if not slako_dir.endswith('/'): slako_dir += '/' if (do_3rd_order and (not pexists(slako_dir + '3rd_order/'))): print( "WARNING: You chose ThirdOrder(Full), but I didn't find the default directory" ) print(" '" + slako_dir + "3rd_order/' for .skf files") print( " Please, make sure they are in the working directory or specified otherwise!" ) elif do_3rd_order: slako_dir += '3rd_order/' else: slako_dir = './' self.default_parameters = dict( Options_='', Options_WriteResultsTag='Yes', Options_WriteCPA='No', Options_WriteDetailedOut='Yes', Analysis_='', Analysis_CalculateForces='Yes', Hamiltonian_='DFTB', Hamiltonian_Scc='Yes', Hamiltonian_SccTolerance=1.0E-005, Hamiltonian_SlaterKosterFiles_='Type2FileNames', Hamiltonian_SlaterKosterFiles_Prefix=slako_dir, Hamiltonian_SlaterKosterFiles_Separator='"-"', Hamiltonian_SlaterKosterFiles_Suffix='".skf"', Hamiltonian_MaxAngularMomentum_='') ## set default maximum angular momentum to consider maxang = 'Hamiltonian_MaxAngularMomentum_' for s in list(set(atoms.get_chemical_symbols())): self.default_parameters[maxang + s] = DefaultMaxAngMom[s] self.pbc = np.any(atoms.pbc) self.default_parameters['Driver'] = '{}' if do_3rd_order: hcorr = 'Hamiltonian_HCorrection_' hubder = 'Hamiltonian_HubbardDerivs_' self.default_parameters[hcorr] = 'Damping' self.default_parameters[hcorr + 'Exponent'] = '4.05' self.default_parameters[hubder] = '' for s in list(set(atoms.get_chemical_symbols())): idU = kwargs.get(hubder + s, 'inputdoesntlooklikethis') if (not (idU == 'inputdoesntlooklikethis')): self.default_parameters[hubder + s] = idU else: try: self.default_parameters[hubder + s] = DefaultdU[s] except KeyError: msg = "Hubbard Derivative for '" + s + "' not found. " msg += "Please specify on input or implement." raise NotImplementedError(msg) FileIOCalculator.__init__(self, restart, ignore_bad_restart_file, label, atoms, **kwargs) self.kpts = kpts # kpoint stuff by ase if self.kpts != None: mpgrid = kpts2mp(atoms, self.kpts) mp = monkhorst_pack(mpgrid) initkey = 'Hamiltonian_KPointsAndWeights' self.parameters[initkey + '_'] = '' for i, imp in enumerate(mp): key = initkey + '_empty' + str(i) self.parameters[key] = str(mp[i]).strip('[]') + ' 1.0' dispkey = 'Hamiltonian_Dispersion_' vdWmethod = self.parameters.get(dispkey, 'No_vdW_method_defined') doMBD = (vdWmethod.lower() == 'mbd') doTS = (vdWmethod.lower() == 'ts') self.CPAavail = (self.parameters['Options_WriteCPA'].lower() == 'yes') self.CPAavail = self.CPAavail and (doMBD or doTS) self.do_vdW = dispkey in self.parameters.keys() if doMBD: if not (dispkey + 'Beta' in self.parameters.keys()): self.parameters[dispkey + 'Beta'] = default_beta_MBD elif doTS: if not (dispkey + 'RangeSeparation' in self.parameters.keys()): self.parameters[dispkey + 'RangeSeparation'] = default_sR_TS if self.pbc and (doMBD or doTS): if not (dispkey + 'KGrid' in self.parameters.keys()): if self.kpts is None: kpts_vdW = '1 1 1' else: kpts_vdW = ' '.join([str(k) for k in self.kpts]) self.parameters[dispkey + 'KGrid'] = kpts_vdW _calc_forces = self.parameters['Analysis_CalculateForces'] self.calculate_forces = (_calc_forces.lower() == 'yes') _writeDet = self.parameters['Options_WriteDetailedOut'] self.writeDetOut = (_writeDet.lower() == 'yes') self.atoms = atoms #the input file written only once if restart == None: self.write_dftb_in() else: if os.path.exists(restart): os.system('cp ' + restart + ' dftb_in.hsd') if not os.path.exists('dftb_in.hsd'): raise IOError('No file "dftb_in.hsd", use restart=None') #indexes for the result file self.first_time = True self.index_energy = None self.index_force_begin = None self.index_force_end = None self.index_stress_begin = None self.index_stress_end = None self.index_charges_begin = None self.index_charges_end = None
def write_elk_in(fd, atoms, parameters=None): if parameters is None: parameters = {} parameters = dict(parameters) species_path = parameters.pop('species_dir', None) if parameters.get('spinpol') is None: if atoms.get_initial_magnetic_moments().any(): parameters['spinpol'] = True if 'xctype' in parameters: if 'xc' in parameters: raise RuntimeError("You can't use both 'xctype' and 'xc'!") if parameters.get('autokpt'): if 'kpts' in parameters: raise RuntimeError("You can't use both 'autokpt' and 'kpts'!") if 'ngridk' in parameters: raise RuntimeError("You can't use both 'autokpt' and 'ngridk'!") if 'ngridk' in parameters: if 'kpts' in parameters: raise RuntimeError("You can't use both 'ngridk' and 'kpts'!") if parameters.get('autoswidth'): if 'smearing' in parameters: raise RuntimeError( "You can't use both 'autoswidth' and 'smearing'!") if 'swidth' in parameters: raise RuntimeError("You can't use both 'autoswidth' and 'swidth'!") inp = {} inp.update(parameters) if 'xc' in parameters: xctype = { 'LDA': 3, # PW92 'PBE': 20, 'REVPBE': 21, 'PBESOL': 22, 'WC06': 26, 'AM05': 30, 'mBJLDA': (100, 208, 12) }[parameters['xc']] inp['xctype'] = xctype del inp['xc'] if 'kpts' in parameters: # XXX should generalize kpts handling. from ase.calculators.calculator import kpts2mp mp = kpts2mp(atoms, parameters['kpts']) inp['ngridk'] = tuple(mp) vkloff = [] # is this below correct? for nk in mp: if nk % 2 == 0: # shift kpoint away from gamma point vkloff.append(0.5) else: vkloff.append(0) inp['vkloff'] = vkloff del inp['kpts'] if 'smearing' in parameters: name = parameters.smearing[0].lower() if name == 'methfessel-paxton': stype = parameters.smearing[2] else: stype = { 'gaussian': 0, 'fermi-dirac': 3, }[name] inp['stype'] = stype inp['swidth'] = parameters.smearing[1] del inp['smearing'] # convert keys to ELK units for key, value in inp.items(): if key in elk_parameters: inp[key] /= elk_parameters[key] # write all keys for key, value in inp.items(): fd.write('%s\n' % key) if isinstance(value, bool): fd.write('.%s.\n\n' % ('false', 'true')[value]) elif isinstance(value, (int, float)): fd.write('%s\n\n' % value) else: fd.write('%s\n\n' % ' '.join([str(x) for x in value])) # cell fd.write('avec\n') for vec in atoms.cell: fd.write('%.14f %.14f %.14f\n' % tuple(vec / Bohr)) fd.write('\n') # atoms species = {} symbols = [] for a, (symbol, m) in enumerate( zip(atoms.get_chemical_symbols(), atoms.get_initial_magnetic_moments())): if symbol in species: species[symbol].append((a, m)) else: species[symbol] = [(a, m)] symbols.append(symbol) fd.write('atoms\n%d\n' % len(species)) # scaled = atoms.get_scaled_positions(wrap=False) scaled = np.linalg.solve(atoms.cell.T, atoms.positions.T).T for symbol in symbols: fd.write("'%s.in' : spfname\n" % symbol) fd.write('%d\n' % len(species[symbol])) for a, m in species[symbol]: fd.write('%.14f %.14f %.14f 0.0 0.0 %.14f\n' % (tuple(scaled[a]) + (m, ))) # if sppath is present in elk.in it overwrites species blocks! # Elk seems to concatenate path and filename in such a way # that we must put a / at the end: if species_path is not None: fd.write(f"sppath\n'{species_path}/'\n\n")
def write_input(self, atoms, properties=None, system_changes=None): FileIOCalculator.write_input(self, atoms, properties, system_changes) self.initialize(atoms) self.parameters.write(os.path.join(self.directory, 'parameters.ase')) if 'xctype' in self.parameters: if 'xc' in self.parameters: raise RuntimeError("You can't use both 'xctype' and 'xc'!") if self.parameters.get('autokpt'): if 'kpts' in self.parameters: raise RuntimeError("You can't use both 'autokpt' and 'kpts'!") if 'ngridk' in self.parameters: raise RuntimeError("You can't use both 'autokpt' and 'ngridk'!") if 'ngridk' in self.parameters: if 'kpts' in self.parameters: raise RuntimeError("You can't use both 'ngridk' and 'kpts'!") if self.parameters.get('autoswidth'): if 'smearing' in self.parameters: raise RuntimeError("You can't use both 'autoswidth' and 'smearing'!") if 'swidth' in self.parameters: raise RuntimeError("You can't use both 'autoswidth' and 'swidth'!") fd = open(os.path.join(self.directory, 'elk.in'), 'w') inp = {} inp.update(self.parameters) if 'xc' in self.parameters: xctype = {'LDA': 3, # PW92 'PBE': 20, 'REVPBE': 21, 'PBESOL': 22, 'WC06': 26, 'AM05': 30}[self.parameters.xc] inp['xctype'] = xctype del inp['xc'] if 'kpts' in self.parameters: mp = kpts2mp(atoms, self.parameters.kpts) inp['ngridk'] = tuple(mp) vkloff = [] # is this below correct? for nk in mp: if nk % 2 == 0: # shift kpoint away from gamma point vkloff.append(0.5 / nk) else: vkloff.append(0) inp['vkloff'] = vkloff del inp['kpts'] if 'smearing' in self.parameters: name = self.parameters.smearing[0].lower() if name == 'methfessel-paxton': stype = self.parameters.smearing[2] else: stype = {'gaussian': 0, 'fermi-dirac': 3, }[name] inp['stype'] = stype inp['swidth'] = self.parameters.smearing[1] del inp['smearing'] # convert keys to ELK units for key, value in inp.items(): if key in elk_parameters: inp[key] /= elk_parameters[key] # write all keys for key, value in inp.items(): fd.write('%s\n' % key) if isinstance(value, bool): fd.write('.%s.\n\n' % ('false', 'true')[value]) elif isinstance(value, (int, float)): fd.write('%s\n\n' % value) else: fd.write('%s\n\n' % ' '.join([str(x) for x in value])) # cell fd.write('avec\n') for vec in atoms.cell: fd.write('%.14f %.14f %.14f\n' % tuple(vec / Bohr)) fd.write('\n') # atoms species = {} symbols = [] for a, (symbol, m) in enumerate(zip(atoms.get_chemical_symbols(), atoms.get_initial_magnetic_moments())): if symbol in species: species[symbol].append((a, m)) else: species[symbol] = [(a, m)] symbols.append(symbol) fd.write('atoms\n%d\n' % len(species)) scaled = atoms.get_scaled_positions() for symbol in symbols: fd.write("'%s.in' : spfname\n" % symbol) fd.write('%d\n' % len(species[symbol])) for a, m in species[symbol]: fd.write('%.14f %.14f %.14f 0.0 0.0 %.14f\n' % (tuple(scaled[a])+ (m,))) # species species_path = self.parameters.get('species_dir') if species_path is None: species_path = os.environ.get('ELK_SPECIES_PATH') if species_path is None: raise RuntimeError( 'Missing species directory! Use species_dir ' + 'parameter or set $ELK_SPECIES_PATH environment variable.') # if sppath is present in elk.in it overwrites species blocks! fd.write("sppath\n'%s'\n\n" % species_path)
# save all steps in one traj file in addition to the database # we should only used the database c.reserve, but here # traj file is used as another lock ... fd = opencew(name + '_' + code + '.traj') if fd is None: continue traj = Trajectory(name + '_' + code + '.traj', 'w') atoms = collection[name] if name == 'Mn': # fails to find the right magnetic state atoms.set_initial_magnetic_moments([10., 20., -10., -20.]) if name == 'Co': # fails to find the right magnetic state atoms.set_initial_magnetic_moments([10., 10.]) if name == 'Ni': # fails to find the right magnetic state atoms.set_initial_magnetic_moments([10., 10., 10., 10.]) cell = atoms.get_cell() kpts = tuple(kpts2mp(atoms, kptdensity, even=True)) kwargs = {} # loop over EOS linspace for n, x in enumerate(np.linspace(linspace[0], linspace[1], linspace[2])): id = c.reserve(name=name, ecut=ecut, pawecutdg=pawecutdg, linspacestr=linspacestr, kptdensity=kptdensity, width=width, ecutsm=ecutsm, fband=fband, tolsym=tolsym, x=x) if id is None: continue
# generate species with custom rmt 2.1 rmt = {'Al': 2.1} label = 'rmt2.1' atomsrmt = atoms.copy() os.environ['ELK_SPECIES_PATH'] = ELK_SPECIES_PATH atomsrmt.calc = ELK(tasks=0, label=label, rmt=rmt) # minimal calc atomsrmt.get_potential_energy() del atomsrmt.calc del atomsrmt # hack ELK_SPECIES_PATH to use custom species os.environ['ELK_SPECIES_PATH'] = os.path.abspath(label) + '/' # run calculation calc = ELK(tasks=0, label=label, rgkmax=4.0, kpts=tuple(kpts2mp(atoms, 2.0, even=True))) atoms.set_calculator(calc) e1 = atoms.get_potential_energy() # test2 # generate species with custom rmt 2.1 rmt = {'Al': -0.1} label = 'rmt0.1m' atomsrmt = atoms.copy() os.environ['ELK_SPECIES_PATH'] = ELK_SPECIES_PATH atomsrmt.calc = ELK(tasks=0, label=label, rmt=rmt) # minimal calc atomsrmt.get_potential_energy() del atomsrmt.calc del atomsrmt
def write_input(self, atoms, properties=None, system_changes=None): FileIOCalculator.write_input(self, atoms, properties, system_changes) self.initialize(atoms) self.parameters.write(os.path.join(self.directory, 'parameters.ase')) if 'xctype' in self.parameters: if 'xc' in self.parameters: raise RuntimeError("You can't use both 'xctype' and 'xc'!") if self.parameters.get('autokpt'): if 'kpts' in self.parameters: raise RuntimeError("You can't use both 'autokpt' and 'kpts'!") if 'ngridk' in self.parameters: raise RuntimeError( "You can't use both 'autokpt' and 'ngridk'!") if 'ngridk' in self.parameters: if 'kpts' in self.parameters: raise RuntimeError("You can't use both 'ngridk' and 'kpts'!") if self.parameters.get('autoswidth'): if 'smearing' in self.parameters: raise RuntimeError( "You can't use both 'autoswidth' and 'smearing'!") if 'swidth' in self.parameters: raise RuntimeError( "You can't use both 'autoswidth' and 'swidth'!") fd = open(os.path.join(self.directory, 'elk.in'), 'w') inp = {} inp.update(self.parameters) if 'xc' in self.parameters: xctype = { 'LDA': 3, # PW92 'PBE': 20, 'REVPBE': 21, 'PBESOL': 22, 'WC06': 26, 'AM05': 30 }[self.parameters.xc] inp['xctype'] = xctype del inp['xc'] if 'kpts' in self.parameters: mp = kpts2mp(atoms, self.parameters.kpts) inp['ngridk'] = tuple(mp) vkloff = [] # is this below correct? for nk in mp: if nk % 2 == 0: # shift kpoint away from gamma point vkloff.append(0.5) else: vkloff.append(0) inp['vkloff'] = vkloff del inp['kpts'] if 'smearing' in self.parameters: name = self.parameters.smearing[0].lower() if name == 'methfessel-paxton': stype = self.parameters.smearing[2] else: stype = { 'gaussian': 0, 'fermi-dirac': 3, }[name] inp['stype'] = stype inp['swidth'] = self.parameters.smearing[1] del inp['smearing'] # convert keys to ELK units for key, value in inp.items(): if key in elk_parameters: inp[key] /= elk_parameters[key] # write all keys for key, value in inp.items(): fd.write('%s\n' % key) if isinstance(value, bool): fd.write('.%s.\n\n' % ('false', 'true')[value]) elif isinstance(value, (int, float)): fd.write('%s\n\n' % value) else: fd.write('%s\n\n' % ' '.join([str(x) for x in value])) # cell fd.write('avec\n') for vec in atoms.cell: fd.write('%.14f %.14f %.14f\n' % tuple(vec / Bohr)) fd.write('\n') # atoms species = {} symbols = [] for a, (symbol, m) in enumerate( zip(atoms.get_chemical_symbols(), atoms.get_initial_magnetic_moments())): if symbol in species: species[symbol].append((a, m)) else: species[symbol] = [(a, m)] symbols.append(symbol) fd.write('atoms\n%d\n' % len(species)) #scaled = atoms.get_scaled_positions(wrap=False) scaled = np.linalg.solve(atoms.cell.T, atoms.positions.T).T for symbol in symbols: fd.write("'%s.in' : spfname\n" % symbol) fd.write('%d\n' % len(species[symbol])) for a, m in species[symbol]: fd.write('%.14f %.14f %.14f 0.0 0.0 %.14f\n' % (tuple(scaled[a]) + (m, ))) # species species_path = self.parameters.get('species_dir') if species_path is None: species_path = os.environ.get('ELK_SPECIES_PATH') if species_path is None: raise RuntimeError( 'Missing species directory! Use species_dir ' + 'parameter or set $ELK_SPECIES_PATH environment variable.') # if sppath is present in elk.in it overwrites species blocks! fd.write("sppath\n'%s'\n\n" % species_path)
def write_input(self, atoms, properties=None, system_changes=None): """Write input parameters to files-file.""" FileIOCalculator.write_input(self, atoms, properties, system_changes) if ('numbers' in system_changes or 'initial_magmoms' in system_changes): self.initialize(atoms) fh = open(self.label + '.files', 'w') fh.write('%s\n' % (self.prefix + '.in')) # input fh.write('%s\n' % (self.prefix + '.txt')) # output fh.write('%s\n' % (self.prefix + 'i')) # input fh.write('%s\n' % (self.prefix + 'o')) # output # XXX: # scratch files #scratch = self.scratch #if scratch is None: # scratch = dir #if not os.path.exists(scratch): # os.makedirs(scratch) #fh.write('%s\n' % (os.path.join(scratch, prefix + '.abinit'))) fh.write('%s\n' % (self.prefix + '.abinit')) # Provide the psp files for ppp in self.ppp_list: fh.write('%s\n' % (ppp)) # psp file path fh.close() # Abinit will write to label.txtA if label.txt already exists, # so we remove it if it's there: filename = self.label + '.txt' if os.path.isfile(filename): os.remove(filename) param = self.parameters param.write(self.label + '.ase') fh = open(self.label + '.in', 'w') inp = {} inp.update(param) for key in ['xc', 'smearing', 'kpts', 'pps', 'raw']: del inp[key] smearing = param.get('smearing') if 'tsmear' in param or 'occopt' in param: assert smearing is None if smearing is not None: inp['occopt'] = {'fermi-dirac': 3, 'gaussian': 7}[smearing[0].lower()] inp['tsmear'] = smearing[1] inp['natom'] = len(atoms) if 'nbands' in param: inp['nband'] = param.nbands del inp['nbands'] if 'ixc' not in param: inp['ixc'] = {'LDA': 7, 'PBE': 11, 'revPBE': 14, 'RPBE': 15, 'WC': 23}[param.xc] magmoms = atoms.get_initial_magnetic_moments() if magmoms.any(): inp['nsppol'] = 2 fh.write('spinat\n') for n, M in enumerate(magmoms): fh.write('%.14f %.14f %.14f\n' % (0, 0, M)) else: inp['nsppol'] = 1 for key in sorted(inp.keys()): value = inp[key] unit = keys_with_units.get(key) if unit is None: fh.write('%s %s\n' % (key, value)) else: if 'fs**2' in unit: value /= fs**2 elif 'fs' in unit: value /= fs fh.write('%s %e %s\n' % (key, value, unit)) if param.raw is not None: for line in param.raw: if isinstance(line, tuple): fh.write(' '.join(['%s' % x for x in line]) + '\n') else: fh.write('%s\n' % line) fh.write('#Definition of the unit cell\n') fh.write('acell\n') fh.write('%.14f %.14f %.14f Angstrom\n' % (1.0, 1.0, 1.0)) fh.write('rprim\n') for v in atoms.cell: fh.write('%.14f %.14f %.14f\n' % tuple(v)) fh.write('chkprim 0 # Allow non-primitive cells\n') fh.write('#Definition of the atom types\n') fh.write('ntypat %d\n' % (len(self.species))) fh.write('znucl') for n, Z in enumerate(self.species): fh.write(' %d' % (Z)) fh.write('\n') fh.write('#Enumerate different atomic species\n') fh.write('typat') fh.write('\n') self.types = [] for Z in atoms.numbers: for n, Zs in enumerate(self.species): if Z == Zs: self.types.append(n + 1) n_entries_int = 20 # integer entries per line for n, type in enumerate(self.types): fh.write(' %d' % (type)) if n > 1 and ((n % n_entries_int) == 1): fh.write('\n') fh.write('\n') fh.write('#Definition of the atoms\n') fh.write('xangst\n') for pos in atoms.positions: fh.write('%.14f %.14f %.14f\n' % tuple(pos)) if 'kptopt' not in param: mp = kpts2mp(atoms, param.kpts) fh.write('kptopt 1\n') fh.write('ngkpt %d %d %d\n' % tuple(mp)) fh.write('nshiftk 1\n') fh.write('shiftk\n') fh.write('%.1f %.1f %.1f\n' % tuple((np.array(mp) + 1) % 2 * 0.5)) fh.write('chkexit 1 # abinit.exit file in the running directory terminates after the current SCF\n') fh.close()
def write_input(self, atoms, properties=tuple(), system_changes=tuple()): """Write input parameters to files-file.""" FileIOCalculator.write_input(self, atoms, properties, system_changes) if ('numbers' in system_changes or 'initial_magmoms' in system_changes): self.initialize(atoms) fh = open(self.label + '.files', 'w') fh.write('%s\n' % (self.prefix + '.in')) # input fh.write('%s\n' % (self.prefix + '.txt')) # output fh.write('%s\n' % (self.prefix + 'i')) # input fh.write('%s\n' % (self.prefix + 'o')) # output # XXX: # scratch files #scratch = self.scratch #if scratch is None: # scratch = dir #if not os.path.exists(scratch): # os.makedirs(scratch) #fh.write('%s\n' % (os.path.join(scratch, prefix + '.abinit'))) fh.write('%s\n' % (self.prefix + '.abinit')) # Provide the psp files for ppp in self.ppp_list: fh.write('%s\n' % (ppp)) # psp file path fh.close() # Abinit will write to label.txtA if label.txt already exists, # so we remove it if it's there: filename = self.label + '.txt' if os.path.isfile(filename): os.remove(filename) param = self.parameters param.write(self.label + '.ase') fh = open(self.label + '.in', 'w') inp = {} inp.update(param) for key in ['xc', 'smearing', 'kpts', 'pps', 'raw']: del inp[key] smearing = param.get('smearing') if 'tsmear' in param or 'occopt' in param: assert smearing is None if smearing is not None: inp['occopt'] = { 'fermi-dirac': 3, 'gaussian': 7 }[smearing[0].lower()] inp['tsmear'] = smearing[1] inp['natom'] = len(atoms) if 'nbands' in param: inp['nband'] = param.nbands del inp['nbands'] # ixc is set from paw/xml file. Ignore 'xc' setting then. if param.get('pps') not in ['pawxml']: if 'ixc' not in param: inp['ixc'] = { 'LDA': 7, 'PBE': 11, 'revPBE': 14, 'RPBE': 15, 'WC': 23 }[param.xc] magmoms = atoms.get_initial_magnetic_moments() if magmoms.any(): inp['nsppol'] = 2 fh.write('spinat\n') for n, M in enumerate(magmoms): fh.write('%.14f %.14f %.14f\n' % (0, 0, M)) else: inp['nsppol'] = 1 for key in sorted(inp.keys()): value = inp[key] unit = keys_with_units.get(key) if unit is None: fh.write('%s %s\n' % (key, value)) else: if 'fs**2' in unit: value /= fs**2 elif 'fs' in unit: value /= fs fh.write('%s %e %s\n' % (key, value, unit)) if param.raw is not None: for line in param.raw: if isinstance(line, tuple): fh.write(' '.join(['%s' % x for x in line]) + '\n') else: fh.write('%s\n' % line) fh.write('#Definition of the unit cell\n') fh.write('acell\n') fh.write('%.14f %.14f %.14f Angstrom\n' % (1.0, 1.0, 1.0)) fh.write('rprim\n') if atoms.number_of_lattice_vectors != 3: raise RuntimeError( 'Abinit requires a 3D cell, but cell is {}'.format(atoms.cell)) for v in atoms.cell: fh.write('%.14f %.14f %.14f\n' % tuple(v)) fh.write('chkprim 0 # Allow non-primitive cells\n') fh.write('#Definition of the atom types\n') fh.write('ntypat %d\n' % (len(self.species))) fh.write('znucl') for n, Z in enumerate(self.species): fh.write(' %d' % (Z)) fh.write('\n') fh.write('#Enumerate different atomic species\n') fh.write('typat') fh.write('\n') self.types = [] for Z in atoms.numbers: for n, Zs in enumerate(self.species): if Z == Zs: self.types.append(n + 1) n_entries_int = 20 # integer entries per line for n, type in enumerate(self.types): fh.write(' %d' % (type)) if n > 1 and ((n % n_entries_int) == 1): fh.write('\n') fh.write('\n') fh.write('#Definition of the atoms\n') fh.write('xangst\n') for pos in atoms.positions: fh.write('%.14f %.14f %.14f\n' % tuple(pos)) if 'kptopt' not in param: mp = kpts2mp(atoms, param.kpts) fh.write('kptopt 1\n') fh.write('ngkpt %d %d %d\n' % tuple(mp)) fh.write('nshiftk 1\n') fh.write('shiftk\n') fh.write('%.1f %.1f %.1f\n' % tuple((np.array(mp) + 1) % 2 * 0.5)) fh.write( 'chkexit 1 # abinit.exit file in the running directory terminates after the current SCF\n' ) fh.close()
def test_Al_rmt(): import os from ase.test import require from ase.build import bulk from ase.calculators.calculator import kpts2mp from ase.calculators.elk import ELK require('elk') atoms = bulk('Al', 'bcc', a=4.0) # save ELK_SPECIES_PATH ELK_SPECIES_PATH = os.environ.get('ELK_SPECIES_PATH', None) assert ELK_SPECIES_PATH is not None # find rmt of the default species sfile = os.path.join(os.environ['ELK_SPECIES_PATH'], 'elk.in') assert os.path.exists(sfile) slines = open(sfile, 'r').readlines() rmt_orig = {} for name in ['Al']: found = False for n, line in enumerate(slines): if line.find("'" + name + "'") > -1: begline = n - 1 for n, line in enumerate(slines[begline:]): if not line.strip(): # first empty line found = True break assert found # split needed because H is defined with comments rmt_orig[name] = float(slines[begline + 3].split()[0].strip()) assert rmt_orig['Al'] == 2.2 # 2.2 Bohr default # test1 # generate species with custom rmt 2.1 rmt = {'Al': 2.1} label = 'rmt2.1' atomsrmt = atoms.copy() os.environ['ELK_SPECIES_PATH'] = ELK_SPECIES_PATH atomsrmt.calc = ELK(tasks=0, label=label, rmt=rmt) # minimal calc atomsrmt.get_potential_energy() del atomsrmt.calc del atomsrmt # hack ELK_SPECIES_PATH to use custom species os.environ['ELK_SPECIES_PATH'] = os.path.abspath(label) + '/' # run calculation calc = ELK(tasks=0, label=label, rgkmax=4.0, kpts=tuple(kpts2mp(atoms, 2.0, even=True))) atoms.calc = calc e1 = atoms.get_potential_energy() # test2 # generate species with custom rmt 2.1 rmt = {'Al': -0.1} label = 'rmt0.1m' atomsrmt = atoms.copy() os.environ['ELK_SPECIES_PATH'] = ELK_SPECIES_PATH atomsrmt.calc = ELK(tasks=0, label=label, rmt=rmt) # minimal calc atomsrmt.get_potential_energy() del atomsrmt.calc del atomsrmt # hack ELK_SPECIES_PATH to use custom species os.environ['ELK_SPECIES_PATH'] = os.path.abspath(label) + '/' # run calculation calc = ELK(tasks=0, label=label, rgkmax=4.0, kpts=tuple(kpts2mp(atoms, 2.0, even=True))) atoms.calc = calc e2 = atoms.get_potential_energy() # restore ELK_SPECIES_PATH os.environ['ELK_SPECIES_PATH'] = ELK_SPECIES_PATH assert abs(e1 - e2) < 1.0e-4
def write_input(self, atoms, properties=None, system_changes=None): """Write input parameters to files-file.""" FileIOCalculator.write_input(self, atoms, properties, system_changes) if ('numbers' in system_changes or 'initial_magmoms' in system_changes): self.initialize(atoms) fh = open(self.label + '.files', 'w') fh.write('%s\n' % (self.prefix + '.in')) # input fh.write('%s\n' % (self.prefix + '.txt')) # output fh.write('%s\n' % (self.prefix + 'i')) # input fh.write('%s\n' % (self.prefix + 'o')) # output # XXX: # scratch files #scratch = self.scratch #if scratch is None: # scratch = dir #if not os.path.exists(scratch): # os.makedirs(scratch) #fh.write('%s\n' % (os.path.join(scratch, prefix + '.abinit'))) fh.write('%s\n' % (self.prefix + '.abinit')) # Provide the psp files for ppp in self.ppp_list: if not os.path.exists('psp'): os.makedirs('psp') newppp = os.path.join('psp', os.path.split(ppp)[-1]) shutil.copyfile(ppp, newppp) fh.write('%s\n' % (newppp)) # psp file path fh.close() # write psp info with open('pspinfo.txt', 'w') as myfile: myfile.write(str(self.pspdict)) # Abinit will write to label.txtA if label.txt already exists, # so we remove it if it's there: filename = self.label + '.txt' if os.path.isfile(filename): os.remove(filename) param = self.parameters param.write(self.label + '.ase') fh = open(self.label + '.in', 'w') inp = {} inp.update(param) for key in ['xc', 'smearing', 'kpts', 'pps', 'raw', 'gamma']: del inp[key] smearing = param.get('smearing') if 'tsmear' in param or 'occopt' in param: assert smearing is None if smearing is not None: inp['occopt'] = { 'fermi-dirac': 3, 'gaussian': 7 }[smearing[0].lower()] inp['tsmear'] = smearing[1] inp['natom'] = len(atoms) if 'nbands' in param: inp['nband'] = param.nbands del inp['nbands'] if 'ixc' not in param: inp['ixc'] = { 'LDA': 1, 'PBE': 11, 'revPBE': 14, 'RPBE': 15, 'WC': 23, 'PBEsol': -116133 }[param.xc] magmoms = atoms.get_initial_magnetic_moments() if magmoms.any(): #inp['nsppol'] = 2 fh.write('spinat\n') for n, M in enumerate(magmoms): fh.write('%.14f %.14f %.14f\n' % (0, 0, M)) else: inp['nsppol'] = 1 #### Mod by Hexu , add Hubbard U######################## if self.U_dict != {}: syms = atoms.get_chemical_symbols() elems = [] for s in syms: if not s in elems: elems.append(s) for s in elems: if s not in self.U_dict: self.U_dict[s] = {'L': -1, 'U': 0, 'J': 0} if self.U_dict != {}: fh.write('# DFT+U\n') fh.write('lpawu %s\n' % (' '.join([str(self.U_dict[s]['L']) for s in elems]))) fh.write('upawu %s eV\n' % (' '.join([str(self.U_dict[s]['U']) for s in elems]))) fh.write('jpawu %s eV\n' % (' '.join([str(self.U_dict[s]['J']) for s in elems]))) for key in sorted(inp.keys()): value = inp[key] unit = keys_with_units.get(key) if unit is None: fh.write('%s %s\n' % (key, value)) else: if 'fs**2' in unit: value /= fs**2 elif 'fs' in unit: value /= fs fh.write('%s %e %s\n' % (key, value, unit)) if param.raw is not None: for line in param.raw: if isinstance(line, tuple): fh.write(' '.join(['%s' % x for x in line]) + '\n') else: fh.write('%s\n' % line) fh.write('#Definition of the unit cell\n') fh.write('acell\n') fh.write('%.14f %.14f %.14f Angstrom\n' % (1.0, 1.0, 1.0)) fh.write('rprim\n') for v in atoms.cell: fh.write('%.14f %.14f %.14f\n' % tuple(v)) fh.write('chkprim 0 # Allow non-primitive cells\n') fh.write('#Definition of the atom types\n') fh.write('ntypat %d\n' % (len(self.species))) fh.write('znucl') for n, Z in enumerate(self.species): fh.write(' %d' % (Z)) fh.write('\n') fh.write('#Enumerate different atomic species\n') fh.write('typat') fh.write('\n') self.types = [] for Z in atoms.numbers: for n, Zs in enumerate(self.species): if Z == Zs: self.types.append(n + 1) n_entries_int = 20 # integer entries per line for n, type in enumerate(self.types): fh.write(' %d' % (type)) if n > 1 and ((n % n_entries_int) == 1): fh.write('\n') fh.write('\n') fh.write('#Definition of the atoms\n') fh.write('xangst\n') for pos in atoms.positions: fh.write('%.14f %.14f %.14f\n' % tuple(pos)) gamma = self.parameters.gamma if 'kptopt' not in param: mp = kpts2mp(atoms, param.kpts) fh.write('kptopt 1\n') fh.write('ngkpt %d %d %d\n' % tuple(mp)) fh.write('nshiftk 1\n') fh.write('shiftk\n') if gamma: fh.write('%.1f %.1f %.1f\n' % tuple( (np.array(mp) + 1) % 2 * 0.0)) else: fh.write('%.1f %.1f %.1f\n' % tuple( (np.array(mp) + 1) % 2 * 0.5)) #----Modified by hexu-----# elif param['kptopt'] in [1, 2, 3, 4]: mp = kpts2mp(atoms, param.kpts) #fh.write('kptopt %s\n'%(param['kptopt'])) fh.write('ngkpt %d %d %d\n' % tuple(mp)) fh.write('nshiftk 1\n') fh.write('shiftk\n') if gamma: fh.write('%.1f %.1f %.1f\n' % tuple( (np.array(mp) + 1) % 2 * 0.0)) else: fh.write('%.1f %.1f %.1f\n' % tuple( (np.array(mp) + 1) % 2 * 0.5)) fh.write( 'chkexit 1 # abinit.exit file in the running directory terminates after the current SCF\n' ) fh.close()
def write_input(self, atoms, properties=None, system_changes=None): FileIOCalculator.write_input(self, atoms, properties, system_changes) self.initialize(atoms) self.parameters.write(os.path.join(self.directory, 'parameters.ase')) if 'xctype' in self.parameters: if 'xc' in self.parameters: raise RuntimeError("You can't use both 'xctype' and 'xc'!") if self.parameters.get('autokpt'): if 'kpts' in self.parameters: raise RuntimeError("You can't use both 'autokpt' and 'kpts'!") if 'ngridk' in self.parameters: raise RuntimeError( "You can't use both 'autokpt' and 'ngridk'!") if 'ngridk' in self.parameters: if 'kpts' in self.parameters: raise RuntimeError("You can't use both 'ngridk' and 'kpts'!") if self.parameters.get('autoswidth'): if 'smearing' in self.parameters: raise RuntimeError( "You can't use both 'autoswidth' and 'smearing'!") if 'swidth' in self.parameters: raise RuntimeError( "You can't use both 'autoswidth' and 'swidth'!") fd = open(os.path.join(self.directory, 'elk.in'), 'w') # handle custom specifications of rmt # (absolute or relative to default) in Bohr # rmt = {'H': 0.7, 'O': -0.2, ...} if self.parameters.get('rmt', None) is not None: self.rmt = self.parameters['rmt'].copy() assert len(self.rmt.keys()) == len(list(set(self.rmt.keys()))), \ 'redundant rmt definitions' self.parameters.pop('rmt') # this is not an elk keyword! else: self.rmt = None inp = {} inp.update(self.parameters) if 'xc' in self.parameters: xctype = { 'LDA': 3, # PW92 'PBE': 20, 'REVPBE': 21, 'PBESOL': 22, 'WC06': 26, 'AM05': 30, 'mBJLDA': (100, 208, 12) }[self.parameters.xc] inp['xctype'] = xctype del inp['xc'] if 'kpts' in self.parameters: mp = kpts2mp(atoms, self.parameters.kpts) inp['ngridk'] = tuple(mp) vkloff = [] # is this below correct? for nk in mp: if nk % 2 == 0: # shift kpoint away from gamma point vkloff.append(0.5) else: vkloff.append(0) inp['vkloff'] = vkloff del inp['kpts'] if 'smearing' in self.parameters: name = self.parameters.smearing[0].lower() if name == 'methfessel-paxton': stype = self.parameters.smearing[2] else: stype = { 'gaussian': 0, 'fermi-dirac': 3, }[name] inp['stype'] = stype inp['swidth'] = self.parameters.smearing[1] del inp['smearing'] # convert keys to ELK units for key, value in inp.items(): if key in elk_parameters: inp[key] /= elk_parameters[key] # write all keys for key, value in inp.items(): fd.write('%s\n' % key) if isinstance(value, bool): fd.write('.%s.\n\n' % ('false', 'true')[value]) elif isinstance(value, (int, float)): fd.write('%s\n\n' % value) else: fd.write('%s\n\n' % ' '.join([str(x) for x in value])) # cell fd.write('avec\n') for vec in atoms.cell: fd.write('%.14f %.14f %.14f\n' % tuple(vec / Bohr)) fd.write('\n') # atoms species = {} symbols = [] for a, (symbol, m) in enumerate( zip(atoms.get_chemical_symbols(), atoms.get_initial_magnetic_moments())): if symbol in species: species[symbol].append((a, m)) else: species[symbol] = [(a, m)] symbols.append(symbol) fd.write('atoms\n%d\n' % len(species)) # scaled = atoms.get_scaled_positions(wrap=False) scaled = np.linalg.solve(atoms.cell.T, atoms.positions.T).T for symbol in symbols: fd.write("'%s.in' : spfname\n" % symbol) fd.write('%d\n' % len(species[symbol])) for a, m in species[symbol]: fd.write('%.14f %.14f %.14f 0.0 0.0 %.14f\n' % (tuple(scaled[a]) + (m, ))) # species species_path = self.parameters.get('species_dir') if species_path is None: species_path = os.environ.get('ELK_SPECIES_PATH') if species_path is None: raise RuntimeError( 'Missing species directory! Use species_dir ' + 'parameter or set $ELK_SPECIES_PATH environment variable.') # custom species definitions if self.rmt is not None: fd.write("\n") sfile = os.path.join(os.environ['ELK_SPECIES_PATH'], 'elk.in') assert os.path.exists(sfile) slines = open(sfile, 'r').readlines() # remove unused species for s in self.rmt.keys(): if s not in species.keys(): self.rmt.pop(s) # add undefined species with defaults for s in species.keys(): if s not in self.rmt.keys(): # use default rmt for undefined species self.rmt.update({s: 0.0}) # write custom species into elk.in skeys = list(set(self.rmt.keys())) # unique skeys.sort() for s in skeys: found = False for n, line in enumerate(slines): if line.find("'" + s + "'") > -1: begline = n - 1 for n, line in enumerate(slines[begline:]): if not line.strip(): # first empty line endline = n found = True break assert found fd.write("species\n") # set rmt on third line rmt = self.rmt[s] assert isinstance(rmt, (float, int)) if rmt <= 0.0: # relative # split needed because H is defined with comments newrmt = (float(slines[begline + 3].split()[0].strip()) + rmt) else: newrmt = rmt slines[begline + 3] = '%6s\n' % str(newrmt) for l in slines[begline:begline + endline]: fd.write('%s' % l) fd.write('\n') else: # use default species # if sppath is present in elk.in it overwrites species blocks! species_path = os.environ['ELK_SPECIES_PATH'] # Elk seems to concatenate path and filename in such a way # that we must put a / at the end: if not species_path.endswith('/'): species_path += '/' fd.write("sppath\n'{}'\n\n".format(species_path))
code = code + "_k" + str(kptdensity) + "_w" + str(width) code = code + "_t" + str(basis_threshold) + "_r" + str(relativistic) collection = Collection() for name in names: # save all steps in one traj file in addition to the database # we should only used the database c.reserve, but here # traj file is used as another lock ... fd = opencew(name + "_" + code + ".traj") if fd is None: continue traj = PickleTrajectory(name + "_" + code + ".traj", "w") atoms = collection[name] cell = atoms.get_cell() kpts = tuple(kpts2mp(atoms, kptdensity, even=True)) kwargs = {} if relativistic == "scalar": kwargs.update({"relativistic": ["atomic_zora", relativistic]}) elif relativistic == "none": kwargs.update({"relativistic": "none"}) else: # e.g. 1.0e-12 kwargs.update({"relativistic": ["zora", relativistic]}) if atoms.get_initial_magnetic_moments().any(): # spin-polarization magmom = atoms.get_initial_magnetic_moments().sum() / len(atoms) kwargs.update({"default_initial_moment": magmom, "spin": "collinear"}) # loop over EOS linspace for n, x in enumerate(np.linspace(linspace[0], linspace[1], linspace[2])): id = c.reserve( name=name, basis=basis,