def run_dftb(system, c, records): calc = Dftb( label='graphene', atoms=graphene, kpts=(1, 1, 1), run_manyDftb_steps=False, # Specific DFTB+ keywords Hamiltonian_SCC='Yes', Hamiltonian_SCCTolerance=1E-5, Hamiltonian_Charge=-1.0, Hamiltonian_Filling_='Fermi', Hamiltonian_Filling_Temperature='1E-6', Hamiltonian_SpinPolarisation_='Colinear', Hamiltonian_SpinPolarisation_UnpairedElectrons=1.0, Hamiltonian_SpinConstants_='', Hamiltonian_SpinConstants_C='{ -0.023}', Hamiltonian_ElectricField_='', Hamiltonian_ElectricField_PointCharges_='', Hamiltonian_ElectricField_PointCharges_CoordsAndCharges_='DirectRead', Hamiltonian_ElectricField_PointCharges_CoordsAndCharges_Records=records, Hamiltonian_ElectricField_PointCharges_CoordsAndCharges_File= 'charges.dat') graphene.set_calculator(calc) calc.calculate(system) return ()
def load_dftb_calculator(directory, atoms): """ Set the tag for a muon in an atoms object Args: directory (str): path to a directory to load DFTB+ results Returns: calculator (ase.calculator.SinglePointCalculator): a single point calculator for the results of the DFTB+ calculation """ results_file = os.path.join(directory, "results.tag") temp_file = os.path.join(directory, "results.tag.bak") # We need to backup the results file here because # .read_results() will remove the results file with BackupFile(results_file, temp_file): calc = Dftb(atoms=atoms) calc.atoms_input = atoms calc.directory = directory calc.read_results() return SinglePointCalculator(atoms, energy=calc.get_potential_energy(), forces=calc.get_forces(), charges=calc.get_charges(atoms), stress=calc.get_stress(atoms))
def __init__(self, atoms, kpts=(1,1,1), use_spline=False, maximum_angular_momenta={}, **kwargs): if type(kpts) == float or type(kpts) == int: mp = kptdensity2monkhorstpack(atoms, kptdensity=kpts, even=False) kpts = tuple(mp) if use_spline: kwargs['Hamiltonian_PolynomialRepulsive'] = 'SetForAll { No }' else: kwargs['Hamiltonian_PolynomialRepulsive'] = 'SetForAll { Yes }' if type(kpts) == float or type(kpts) == int: mp = kptdensity2monkhorstpack(atoms, kptdensity=kpts, even=False) kpts = tuple(mp) kwargs['Hamiltonian_MaxAngularMomentum_'] = '' symbols = atoms.get_chemical_symbols() unique_symbols = list(set(symbols)) for s in unique_symbols: key = 'Hamiltonian_MaxAngularMomentum_%s' % s maxmom = maximum_angular_momenta[s] kwargs[key] = 'spd'[maxmom].__repr__() kwargs['Hamiltonian_SCC'] = 'Yes' kwargs['Hamiltonian_ShellResolvedSCC'] = 'No' Dftb.__init__(self, atoms=atoms, kpts=kpts, **kwargs)
def write_dftb_in(self, filename): if self.read_chg and os.path.exists('charges.bin'): read_charges = 'Yes' else: read_charges = 'No' self.parameters['Hamiltonian_ReadInitialCharges'] = read_charges Dftb.write_dftb_in(self, filename)
def convert_single_structure(cell_file, param_file, directory="."): atoms = io.read(cell_file) io.write(os.path.join(directory, "geo_end.gen"), atoms) with open(param_file, 'r') as stream: castep_params = yaml.load(stream) dftb_params = param_schema.validate({}) # get castep parameters for castep_name, dftb_name in CASTEP_to_DFTB_map.items(): if castep_name in castep_params: dftb_params[dftb_name] = castep_params[castep_name] # get k-points from cell file k_points = map(int, atoms.calc.cell.kpoints_mp_grid.value.split()) dargs = DFTBArgs(dftb_params['dftb_set']) custom_species = atoms.get_array('castep_custom_species') muon_index = np.where(custom_species == dftb_params['mu_symbol'])[0][0] # Add muon mass args = dargs.args args['Driver_'] = 'ConjugateGradient' args['Driver_Masses_'] = '' args['Driver_Masses_Mass_'] = '' args['Driver_Masses_Mass_Atoms'] = '{}'.format(muon_index) args['Driver_Masses_Mass_MassPerAtom [amu]'] = '0.1138' args['Driver_MaxSteps'] = dftb_params['geom_steps'] args['Driver_MaxForceComponent [eV/AA]'] = dftb_params['geom_force_tol'] calc = Dftb(atoms=atoms, kpts=k_points, run_manyDftb_steps=True, **args) calc.write_dftb_in(os.path.join(directory, "dftb_in.hsd"))
def asephonons_entry(): from ase import io from ase.calculators.dftb import Dftb from pymuonsuite.data.dftb_pars import DFTBArgs parser = ap.ArgumentParser(description="Compute phonon modes with ASE and" " DFTB+ for reuse in quantum effects " "calculations.") parser.add_argument('structure_file', type=str, help="Structure for which to compute the phonons") parser.add_argument('parameter_file', type=str, help="YAML file containing relevant input parameters") args = parser.parse_args() # Load parameters params = load_input_file(args.parameter_file, AsePhononsSchema) fname, fext = os.path.splitext(args.structure_file) if params['name'] is None: params['name'] = fname # Load structure a = io.read(args.structure_file) # Create a Dftb calculator dargs = DFTBArgs(params['dftb_set']) # Is it periodic? if params['pbc']: a.set_pbc(True) calc = Dftb(atoms=a, label='asephonons', kpts=params['kpoint_grid'], **dargs.args) ph_kpts = params['phonon_kpoint_grid'] else: a.set_pbc(False) calc = Dftb(atoms=a, label='asephonons', **dargs.args) ph_kpts = None a.set_calculator(calc) phdata = ase_phonon_calc(a, kpoints=ph_kpts, ftol=params['force_tol'], force_clean=params['force_clean'], name=params['name']) # Save optimised structure io.write(params['name'] + '_opt' + fext, phdata.structure) # And write out the phonons outf = params['name'] + '_opt.phonons.pkl' pickle.dump(phdata, open(outf, 'wb')) write_phonon_report(args, params, phdata)
def dftb_BS(skf, TMP=2000, kp=[16, 16, 16], UPE=3, A=np.array([[-0.016, -0.012, -0.003], [-0.012, -0.029, -0.001], [-0.003, -0.001, -0.015]])): Filling = "MethfesselPaxton { \n Temperature [Kelvin] = %.1d\n Order= 2\n}" % ( TMP) MAN = [["Fe", "d"]] # Max angular momentum ([sp1,couche],[sp2,couche],...) scaling = 1.0 calc = Dftb( label='relax_BS', MAG=True, skf='{}'.format(skf), RSPIN='Yes', UPE=UPE, Hamiltonian_SCC="Yes", Hamiltonian_SCCTolerance="1E-5", Hamiltonian_MaxAngularMomentum=MAN, Hamiltonian_MaxSCCIterations=1, Hamiltonian_KPointsAndWeights= "Klines {\n 0 0 0 0 # G\n 50 0.5 -0.5 0.5 # H\n 50 0 0 0.5 # N\n 50 0 0 0 # G\n 50 0.25 0.25 0.25 # P\n 50 0.5 -0.5 0.5 # H\n 0 0.25 0.25 0.25 # P\n 50 0 0 0.5 # N\n }", Hamiltonian_OrbitalResolvedSCC="Yes", Hamiltonian_Charge="0.0", Hamiltonian_SpinConstants=' { \n Fe = {\n ' + '{} {} {} \n {} {} {} \n {} {} {} \n'.format( A[0][0], A[0][1], A[0][2], A[1][0], A[1][1], A[1][2], A[2][0], A[2][1], A[2][2]) + ' }\n }', Options_WriteChargesAsText="Yes", Hamiltonian_Filling=Filling, Parallel_UseOmpThreads="Yes", Hamiltonian_Mixer= "Broyden {\n MixingParameter = 0.05 \n InverseJacobiWeight = 0.01 \n MinimalWeight = 1.0 \n MaximalWeight = 1e5 \n WeightFactor = 100 \n}" ) return calc
def main(): '''Main driver routine.''' initial = read('NH3_initial.traj') final = read('NH3_final.traj') images = [initial] images += [initial.copy() for ii in range(NIMAGES)] images += [final] neb = NEB(images) neb.interpolate() opt = BFGS(neb, trajectory='i2f.traj') calcs = [ Dftb(label='NH3_inversion', Hamiltonian_SCC='Yes', Hamiltonian_SCCTolerance='1.00E-06', Hamiltonian_MaxAngularMomentum_N='"p"', Hamiltonian_MaxAngularMomentum_H='"s"') for ii in range(NIMAGES) ] for ii, calc in enumerate(calcs): images[ii + 1].set_calculator(calc) opt.run(fmax=1.00E-02)
def test_dftb_relax_bulk(): import os from ase.test import require from ase.test.testsuite import datafiles_directory from ase.build import bulk from ase.calculators.dftb import Dftb from ase.optimize import QuasiNewton from ase.constraints import ExpCellFilter require('dftb') os.environ['DFTB_PREFIX'] = datafiles_directory calc = Dftb(label='dftb', kpts=(3,3,3), Hamiltonian_SCC='Yes') atoms = bulk('Si') atoms.set_calculator(calc) ecf = ExpCellFilter(atoms) dyn = QuasiNewton(ecf) dyn.run(fmax=0.01) e = atoms.get_potential_energy() assert abs(e - -73.150819) < 1., e
def __setASECalculator(self): """Initialize the calculator and set the parameters""" method = self.definedParams['method'] if method == 'dftb_std-dDMC': self.__setdDMCParams() from ase.calculators.dftbddmc import DftbdDMC self.calculator = DftbdDMC(atoms=self.mol, label='cazzo', dftbdict=self.__dftb_parameters, ddmcdict=self.__ddmc_parameters) elif method == 'dftb_std': from ase.calculators.dftb import Dftb self.calculator = Dftb(atoms=self.mol, label='asd') elif method == 'dftb_std-D3': from ase.calculators.dftbd3h4 import DftbD3H4 self.calculator = DftbD3H4(atoms=self.mol, label='cazzo', dftbdict=self.__dftb_parameters) elif method == 'dftb_std-D3H4': from ase.calculators.dftbd3h4 import DftbD3H4 self.calculator = DftbD3H4(atoms=self.mol, label='cazzo', dftbdict=self.__dftb_parameters) else: raise ImplementationError( method, 'Calculator for this method is not implemented') self.calculator.parameters.update(self.__dftb_parameters)
def test_dftb_relax_dimer(): import os from ase import Atoms from ase.test import require from ase.test.testsuite import datafiles_directory from ase.calculators.dftb import Dftb from ase.optimize import BFGS require('dftb') os.environ['DFTB_PREFIX'] = datafiles_directory calc = Dftb( label='dftb', Hamiltonian_SCC='No', Hamiltonian_PolynomialRepulsive='SetForAll {Yes}', ) atoms = Atoms('Si2', positions=[[5., 5., 5.], [7., 5., 5.]], cell=[12.] * 3, pbc=False) atoms.set_calculator(calc) dyn = BFGS(atoms, logfile='-') dyn.run(fmax=0.1) e = atoms.get_potential_energy() assert abs(e - -64.830901) < 1., e
def __init__(self, label='dftbddmc', atoms=None, dftbdict={}, ddmcdict={}, **kwargs): """Construct a DFTB+ and a dDMC calculator. """ os.environ['ASE_DFTBDDMC_COMMAND'] = '' self.label = label self.dftbdict = dftbdict self.ddmcdict = ddmcdict ddmc_default_parameters = {} ddmc_default_parameters['param_a'] = 1.85705835084132 ddmc_default_parameters['param_b'] = 1.01824853175310 ddmc_default_parameters['param_c'] = 23.0 ddmc_default_parameters['dftype'] = 3 ddmc_default_parameters['tagtype'] = 'dftbp' for param in ddmc_default_parameters.keys(): if not param in self.ddmcdict.keys(): self.ddmcdict[param] = ddmc_default_parameters[param] restart = None ignore_bad_restart_file = None FileIOCalculator.__init__(self, restart, ignore_bad_restart_file, label, atoms, **kwargs) self.dftb_calc = Dftb(label=self.label) self.ddmc_calc = dDMC(label=self.label)
def optimize(self, calculator='siesta'): from ase.optimize import QuasiNewton if calculator == 'siesta': calc = Siesta( label=self.label, xc='CA', mesh_cutoff=400 * eV, energy_shift=0.03 * eV, basis_set='SZ', fdf_arguments=self.extra_fdf, ) elif calculator == 'dftb': extras = {} for S in set(self.mol.get_chemical_symbols()): key = 'Hamiltonian_MaxAngularMomentum_' + S if S == 'H': value = '"s"' else: value = '"p"' extras[key] = value calc = Dftb(label=self.label, atoms=self.mol, **extras) tempdir = "." + self.label try: os.mkdir(tempdir) except: pass os.chdir(tempdir) self.mol.set_calculator(calc) dyn = QuasiNewton(self.mol, trajectory=self.label + '.traj') dyn.run(fmax=0.5) os.chdir('../')
def dftb_1A(skf, TMP=2000, UPE=2): print(skf) Filling = "MethfesselPaxton { \n Temperature [Kelvin] = %.1d\n Order= 2\n}" % ( TMP) MAN = [["Fe", "d"]] # Max angular momentum ([sp1,couche],[sp2,couche],...) scaling = 1.0 A = scaling * np.array([[-0.016, -0.012, -0.003], [-0.012, -0.029, -0.001], [-0.003, -0.001, -0.015]]) # Spin coupling calc = Dftb( label='relax_mag_OFF', MAG=False, skf='{}'.format(skf), RSPIN='Yes', UPE=UPE, Hamiltonian_SCC="Yes", Hamiltonian_SCCTolerance="1E-5", Hamiltonian_MaxAngularMomentum=MAN, Hamiltonian_OrbitalResolvedSCC="Yes", Hamiltonian_MaxSCCIterations="1000", Hamiltonian_Charge="0.0", Options_WriteChargesAsText="Yes", Hamiltonian_Filling=Filling, Parallel_UseOmpThreads="Yes", Hamiltonian_Mixer= "Broyden {\n MixingParameter = 0.05 \n InverseJacobiWeight = 0.01 \n MinimalWeight = 1.0 \n MaximalWeight = 1e5 \n WeightFactor = 100 \n}" ) return calc
def make_dftb_calc(atoms, folder, params): """Make a DFTB+ calculator with the supplied parameters Args: atoms (ase.Atoms): an atoms object to create the DFTB+ calculator for folder (str): directory where the structure files are located. params (dict): dictionary of parameters to pass to the calculator Returns: dcalc (ase.calculators.dftb.Dftb): DFTB+ calculator setup with the provided parameters """ name = os.path.split(folder)[-1] atoms.set_pbc(params['dftb_pbc']) dargs = DFTBArgs(params['dftb_set']) # Add muon mass args = dargs.args args['Driver_'] = 'ConjugateGradient' args['Driver_Masses_'] = '' args['Driver_Masses_Mass_'] = '' args['Driver_Masses_Mass_Atoms'] = '{}'.format(len(atoms.positions)) args['Driver_Masses_Mass_MassPerAtom [amu]'] = '0.1138' if 'geom_force_tol' in params: args['Driver_MaxForceComponent [eV/AA]'] = params['geom_force_tol'] # Max steps is zero because we don't want to optimize with DFTB+. Instead # we just evaluate using DFTB+ let the ASE LBFGS optimizer do the work. args['Driver_MaxSteps'] = '0' # The run_manyDftb_steps option is required here to prevent DFTB+ # overwriting some of the options we set. if params['dftb_pbc']: dcalc = Dftb(label=name, atoms=atoms, kpts=params['k_points_grid'], run_manyDftb_steps=True, **args) else: dcalc = Dftb(label=name, atoms=atoms, run_manyDftb_steps=True, **args) dcalc.directory = folder return dcalc
def calculate_bandstructure(self, bs): """ Returns a BandStructure object with a DFTB band structure. Assumes that the necessary *-*.skf files have been generated. bs: ase.dft.band_structure.BandStructure instance with an additional 'atoms' and 'kpts_scf' attributes. The latter represents the k-points to be used in the self-consistent calculation prior to the bandstructure calculation in DFTB. """ # Perform a regular DFTB calculation first # to converge the charges and get the # reference energy atoms = bs.atoms.copy() calc = Dftb(atoms=atoms, kpts=bs.kpts_scf, **self.dftbplus_kwargs) atoms.set_calculator(calc) etot = atoms.get_potential_energy() efermi = calc.get_fermi_level() if bs.reference_level == 'vbm': eig = np.array(calc.results['eigenvalues']) eref = np.max(eig[eig < efermi]) elif bs.reference_level == 'fermi': eref = efermi # Now a band structure calculation kwargs = self.dftbplus_kwargs.copy() kwargs.update({ 'Hamiltonian_MaxSCCIterations': 1, 'Hamiltonian_ReadInitialCharges': 'Yes', 'Hamiltonian_SCCTolerance': 1e6 }) calc = Dftb(atoms=atoms, kpts=bs.path.kpts, **kwargs) atoms.set_calculator(calc) etot = atoms.get_potential_energy() # Update the reference level, k-points, # and eigenenergies bs_new = copy.deepcopy(bs) #bs_new.reference = eref bs_new_reference = eref bs_new.kpts = calc.get_ibz_k_points() #bs_new.energies = [] bs_new_energies = [] for s in range(calc.get_number_of_spins()): #bs_new.energies.append([calc.get_eigenvalues(kpt=k, spin=s) bs_new_energies.append([ calc.get_eigenvalues(kpt=k, spin=s) for k in range(len(bs_new.kpts)) ]) #bs_new.energies = np.array(bs_new.energies) bs_new_energies = np.array(bs_new_energies) return bs_new
def getImageAndEnergy(stuff): index, atoms, dftb_options, parser = stuff system = copy.deepcopy(atoms) system.rattle(stdev=0.1) system.wrap() dftb_options['atoms'] = system dftb_options['label'] = str(index) + '/' system.set_calculator(Dftb(**dftb_options)) image, E = randRotateAndTranslateWrap((parser, system)) return image, E
def __init__(self, atoms, kpts=(1, 1, 1), use_spline=False, maximum_angular_momenta={}, read_chg=False, label='dftb_run', **extra_dftbplus_kwargs): if type(kpts) == float or type(kpts) == int: mp = kptdensity2monkhorstpack(atoms, kptdensity=kpts, even=False) kpts = tuple(mp) s = 'No' if use_spline else 'Yes' polyrep = 'SetForAll { %s }' % s self.read_chg = read_chg parameters = { 'Hamiltonian_SCC': 'Yes', 'Hamiltonian_OrbitalResolvedSCC': 'Yes', 'Hamiltonian_SCCTolerance': '1e-5', 'Hamiltonian_MaxSCCIterations': 250, 'Hamiltonian_MaxAngularMomentum_': '', 'Hamiltonian_Charge': '0.000000', 'Hamiltonian_ReadInitialCharges': 'No', 'Hamiltonian_Filling': 'Fermi {', 'Hamiltonian_Filling_empty': 'Temperature [Kelvin] = 500', 'Hamiltonian_PolynomialRepulsive': polyrep, 'Hamiltonian_Eigensolver': 'RelativelyRobust {}', } symbols = atoms.get_chemical_symbols() unique_symbols = list(set(symbols)) for s in unique_symbols: key = 'Hamiltonian_MaxAngularMomentum_%s' % s maxmom = maximum_angular_momenta[s] parameters[key] = 'spd'[maxmom].__repr__() parameters.update(extra_dftbplus_kwargs) Dftb.__init__(self, label=label, kpts=kpts, atoms=atoms, **parameters)
def add_calculator(self): extras = {} for S in set(self.get_chemical_symbols()): key = 'Hamiltonian_MaxAngularMomentum_'+S if S=='H': value = '"s"' else: value = '"p"' extras[key]=value self.set_calculator(Dftb(label=self.label, atoms=self, **extras))
def calc(self, **kwargs): from ase.calculators.dftb import Dftb # XXX datafiles should be imported from datafiles project # We should include more datafiles for DFTB there, and remove them # from ASE's own datadir. command = f'{self.executable} > PREFIX.out' datadir = Path(__file__).parent / 'testdata' assert datadir.exists() return Dftb(command=command, slako_dir=str(datadir) + '/', # XXX not obvious **kwargs)
def save_muonconf_dftb(a, folder, params, dftbargs={}): from pymuonsuite.data.dftb_pars import DFTBArgs name = os.path.split(folder)[-1] a.set_pbc(params['dftb_pbc']) dargs = DFTBArgs(params['dftb_set']) custom_species = a.get_array('castep_custom_species') muon_index = np.where(custom_species == params['mu_symbol'])[0][0] is_spinpol = params.get('spin_polarized', False) if is_spinpol: dargs.set_optional('spinpol.json', True) # Add muon mass args = dargs.args args['Driver_'] = 'ConjugateGradient' args['Driver_Masses_'] = '' args['Driver_Masses_Mass_'] = '' args['Driver_Masses_Mass_Atoms'] = '{}'.format(muon_index) args['Driver_Masses_Mass_MassPerAtom [amu]'] = '0.1138' args['Driver_MaxForceComponent [eV/AA]'] = params['geom_force_tol'] args['Driver_MaxSteps'] = params['geom_steps'] args['Driver_MaxSccIterations'] = params['max_scc_steps'] if is_spinpol: # Configure initial spins spins = np.array(a.get_initial_magnetic_moments()) args['Hamiltonian_SpinPolarisation_InitialSpins'] = '{' args['Hamiltonian_SpinPolarisation_' + 'InitialSpins_AllAtomSpins'] = '{' + '\n'.join( map(str, spins)) + '}' args['Hamiltonian_SpinPolarisation_UnpairedElectrons'] = str( np.sum(spins)) # Add any custom arguments if isinstance(dftbargs, DFTBArgs): args.update(dftbargs.args) else: args.update(dftbargs) if params['dftb_pbc']: dcalc = Dftb(label=name, atoms=a, kpts=params['k_points_grid'], run_manyDftb_steps=True, **args) else: dcalc = Dftb(label=name, atoms=a, run_manyDftb_steps=True, **args) dcalc.directory = folder dcalc.write_input(a)
def create_muairss_dftb_calculator(a, params={}, calc=None): from pymuonsuite.data.dftb_pars.dftb_pars import DFTBArgs if not isinstance(calc, Dftb): args = {} else: args = calc.todict() dargs = DFTBArgs(params['dftb_set']) for opt in params['dftb_optionals']: try: dargs.set_optional(opt, True) except KeyError: print(('WARNING: optional DFTB+ file {0} not available for {1}' ' parameter set, skipping').format(opt, params['dftb_set']) ) args.update(dargs.args) args = dargs.args args['Driver_'] = 'ConjugateGradient' args['Driver_Masses_'] = '' args['Driver_Masses_Mass_'] = '' args['Driver_Masses_Mass_Atoms'] = '-1' args['Driver_Masses_Mass_MassPerAtom [amu]'] = str(cnst.m_mu_amu) args['Driver_MaxForceComponent [eV/AA]'] = params['geom_force_tol'] args['Driver_MaxSteps'] = params['geom_steps'] args['Driver_MaxSccIterations'] = params['max_scc_steps'] args['Hamiltonian_Charge'] = 1.0 if params['charged'] else 0.0 if params['dftb_pbc']: calc = Dftb(kpts=params['k_points_grid'], **args) else: calc = Dftb(**args) return calc
def main(): '''Main driver routine.''' system = read(GEO_PATH, format='gen') calc = Dftb(label='H2O_cluster', atoms=system, Hamiltonian_SCC='Yes', Hamiltonian_SCCTolerance='1.00E-010', Driver_='ConjugateGradient', Driver_MaxForceComponent='1.00E-008', Driver_MaxSteps=1000, Hamiltonian_MaxAngularMomentum_='', Hamiltonian_MaxAngularMomentum_O='"p"', Hamiltonian_MaxAngularMomentum_H='"s"') system.set_calculator(calc) calc.calculate(system) final = read('geo_end.gen') forces = system.get_forces() energy = system.get_potential_energy()
def set_dftb_calculator(atoms): from ase.calculators.dftb import Dftb atoms.set_calculator( Dftb( label='c6h6', run_manyDftb_steps=True, Driver_='ConjugateGradient', Driver_MaxForceComponent='1E-3', Driver_MaxSteps=50, atoms=atoms, slako_dir="SKFiles/", Hamiltonian_MaxAngularMomentum_C='"p"', Hamiltonian_MaxAngularMomentum_H='"s"', ))
def create_spinpol_dftbp_calculator(calc=None, param_set='3ob-3-1', kpts=None): """Create a calculator containing all necessary parameters for a DFTB+ SCC spin polarised calculation""" from pymuonsuite.data.dftb_pars import DFTBArgs if not isinstance(calc, Dftb): calc = Dftb() else: calc = deepcopy(calc) # A bit of a hack for the k-points if kpts is not None: kc = Dftb(kpts=kpts) kargs = {k: v for k, v in kc.parameters.items() if 'KPoints' in k} calc.parameters.update(kargs) # Create the arguments dargs = DFTBArgs(param_set) # Make it spin polarised try: dargs.set_optional('spinpol.json', True) except KeyError: raise ValueError('DFTB+ parameter set does not allow spin polarised' ' calculations') # Fix a few things, and add a spin on the muon args = dargs.args del (args['Hamiltonian_SpinPolarisation']) args['Hamiltonian_SpinPolarisation_'] = 'Colinear' args['Hamiltonian_SpinPolarisation_UnpairedElectrons'] = 1 args['Hamiltonian_SpinPolarisation_InitialSpins_'] = '' args['Hamiltonian_SpinPolarisation_InitialSpins_Atoms'] = '-1' args['Hamiltonian_SpinPolarisation_InitialSpins_SpinPerAtom'] = 1 calc.parameters.update(args) calc.do_forces = True return calc
def dftb_calc(path, calc_folder, sys): os.chdir(path) i = 0 if os.path.exists(calc_folder): calc_folder += '_{0}'.format(i) while os.path.exists(calc_folder): i += 1 last_underscore = calc_folder.rfind('_') calc_folder = calc_folder[:last_underscore+1] + str(i) os.makedirs(calc_folder) os.chdir(calc_folder) # Assuming C and H are always present args = {} if 'N' in sys.get_chemical_symbols(): args['Hamiltonian_MaxAngularMomentum_N'] = '"p"' if 'O' in sys.get_chemical_symbols(): args['Hamiltonian_MaxAngularMomentum_O'] = '"p"' calc = Dftb(label=calc_folder, atoms=sys, run_manyDftb_steps=True, # WriteResultsTag='Yes', Driver_='ConjugateGradient', Driver_MaxForceComponent='1E-4', Driver_MaxSteps=1000, Hamiltonian_MaxAngularMomentum_='', Hamiltonian_MaxAngularMomentum_C='"p"', Hamiltonian_MaxAngularMomentum_H='"s"', **args) sys.set_calculator(calc) sys.write('geo_start.xyz') calc.calculate(sys) os.chdir(os.pardir) return calc
def load_muonconf_dftb(folder): """Read a DFTB+ output non-destructively. Args: directory (str): path to a directory to load DFTB+ results Returns: atoms (ase.Atoms): an atomic structure with the results attached in a SinglePointCalculator """ atoms = io.read(os.path.join(folder, 'geo_end.gen')) atoms.info['name'] = os.path.split(folder)[-1] results_file = os.path.join(folder, "results.tag") if os.path.isfile(results_file): # DFTB+ was used to perform the optimisation temp_file = os.path.join(folder, "results.tag.bak") # We need to backup the results file here because # .read_results() will remove the results file with BackupFile(results_file, temp_file): calc = Dftb(atoms=atoms) calc.atoms_input = atoms calc.directory = folder calc.read_results() energy = calc.get_potential_energy() forces = calc.get_forces() charges = calc.get_charges(atoms) calc = SinglePointCalculator(atoms, energy=energy, forces=forces, charges=charges) atoms.set_calculator(calc) return atoms
def main(): '''Main driver routine.''' system = read(GEO_PATH, format='gen') system.set_calculator(Dftb(label='H2O_cluster', atoms=system, Hamiltonian_SCC='Yes', Hamiltonian_SCCTolerance=1.00E-010, Hamiltonian_MaxAngularMomentum_='', Hamiltonian_MaxAngularMomentum_O='"p"', Hamiltonian_MaxAngularMomentum_H='"s"')) opt = BFGS(system, trajectory='opt.traj', logfile='opt.log') opt.run(fmax=1.00E-008) forces = system.get_forces() energy = system.get_potential_energy()
def set_dftb_calculator_for_sp(atoms): """single point calculation using dftb calculator Parameters ---------- atoms: the ase Atoms object to be set """ import os os.environ["DFTB_COMMAND"] = "dftb+" os.environ["DFTB_PREFIX"] = "/home/ybyygu/Incoming/liuxc-dftb+/dftb-params/3ob-3-1" from ase.calculators.dftb import Dftb atoms.set_calculator(Dftb(atoms=atoms, Hamiltonian_MaxAngularMomentum_C='"p"', Hamiltonian_MaxAngularMomentum_O='"p"', Hamiltonian_MaxAngularMomentum_N='"p"', Hamiltonian_MaxAngularMomentum_H='"s"', ))
def dftb_write_input(a, folder, calc=None, name=None, script=None): """Writes input files for an Atoms object with a Dftb+ calculator. | Args: | a (ase.Atoms): Atoms object to write. Can have a Dftb | calculator attached to carry | arguments. | folder (str): Path to save the input files to. | calc (ase.Calculator): Calculator to attach to Atoms. If | present, the pre-existent one will | be ignored. | name (str): Seedname to save the files with. If not | given, use the name of the folder. | script (str): Path to a file containing a submission script | to copy to the input folder. The script can | contain the argument {seedname} in curly braces, | and it will be appropriately replaced. """ if name is None: name = os.path.split(folder)[-1] # Same as folder name if calc is not None: calc.atoms = a a.set_calculator(calc) if not isinstance(a.calc, Dftb): a = a.copy() calc = Dftb(label=name, atoms=a, run_manyDftb_steps=True) a.set_calculator(calc) a.calc.label = name a.calc.directory = folder a.calc.write_input(a) if script is not None: stxt = open(script).read() stxt = stxt.format(seedname=name) with open(os.path.join(folder, 'script.sh'), 'w') as sf: sf.write(stxt)
from ase.calculators.dftb import Dftb from ase.io import write, read from ase.build import molecule system = molecule('H2O') calc = Dftb(label='h2o', atoms=system, run_manyDftb_steps=True, Driver_='ConjugateGradient', Driver_MaxForceComponent='1E-4', Driver_MaxSteps=1000, Hamiltonian_MaxAngularMomentum_='', Hamiltonian_MaxAngularMomentum_O='"p"', Hamiltonian_MaxAngularMomentum_H='"s"') system.set_calculator(calc) calc.calculate(system) final = read('geo_end.gen') write('test.final.xyz', final)