def __init__(self, atoms, Excitations, indices=None, gsname='rraman', # name for ground state calculations exname=None, # name for excited state calculations delta=0.01, nfree=2, directions=None, approximation='Profeta', observation={'geometry': '-Z(XX)Z'}, exkwargs={}, # kwargs to be passed to Excitations exext='.ex.gz', # extension for Excitation names txt='-', verbose=False,): assert(nfree == 2) Vibrations.__init__(self, atoms, indices, gsname, delta, nfree) self.name = gsname + '-d%.3f' % delta if exname is None: exname = gsname self.exname = exname + '-d%.3f' % delta self.exext = exext if directions is None: self.directions = np.array([0, 1, 2]) else: self.directions = np.array(directions) self.approximation = approximation self.observation = observation self.exobj = Excitations self.exkwargs = exkwargs self.timer = Timer() self.txt = convert_string_to_fd(txt) self.verbose = verbose
def run(job, atoms): kwargs = {'mode': 0, 'label': 'vib-{0}'.format(job, job), 'xc': 'PBE', 'scf_guess': 'atomic', 'max_scf': 500, 'EPS_SCF': 5.0E-7, 'added_mos': 500, 'sme/method': 'fermi_dirac', 'ELECTRONIC_TEMPERATURE': 300, 'DIA/ALGORITHM': 'STANDARD', 'mix/METHOD': 'BROYDEN_MIXING', 'ALPHA': 0.1, 'BETA': 1.5, 'NBUFFER': 8, 'cpu': 36, 'cutoff': 300, 'run_type': 'ENERGY_FORCE', # ENERGY_FORCE, GEO_OPT, CELL_OPT, MD 'atoms': atoms, } calc = CP2K(**kwargs) atoms.set_calculator(calc) vib = Vibrations(atoms, indices = [65, 69]) vib.run() vib.summary()
def __init__(self, atoms, siesta, indices=None, name='ram', delta=0.01, nfree=2, directions=None, freq_pol=0.0, **kw): Vibrations.__init__(self, atoms, indices=indices, name=name, delta = delta, nfree=nfree) if atoms.constraints: warnings.warn('WARNING! \n Your Atoms object is constrained. ' + 'Some forces may be unintended set to zero. \n') self.name = name + '-d%.3f' % delta self.calc = atoms.get_calculator() if directions is None: self.directions = np.asarray([0, 1, 2]) else: self.directions = np.asarray(directions) self.ir = True self.ram = True self.siesta = siesta if isinstance(freq_pol, list): self.freq_pol = np.array(freq_pol) elif isinstance(freq_pol, float): self.freq_pol = np.array([freq_pol]) elif isinstance(freq_pol, float) or isinstance(freq_pol, np.ndarray): self.freq_pol = freq_pol else: raise ValueError("wrong type for freq_pol, only float, list or array") self.pyscf_arg = kw
def __init__(self, atoms, Excitations, indices=None, gsname='rraman', # name for ground state calculations exname=None, # name for excited state calculations delta=0.01, nfree=2, directions=None, exkwargs={}, # kwargs to be passed to Excitations txt='-'): assert(nfree == 2) Vibrations.__init__(self, atoms, indices, gsname, delta, nfree) self.name = gsname + '-d%.3f' % delta if exname is None: exname = gsname self.exname = exname + '-d%.3f' % delta if directions is None: self.directions = np.array([0, 1, 2]) else: self.directions = np.array(directions) self.exobj = Excitations self.exkwargs = exkwargs self.timer = Timer() self.txt = get_txt(txt, rank)
def ase_vib(embedder, coords, atomnos, logfunction=None, title='temp'): ''' ''' atoms = Atoms(atomnos, positions=coords) atoms.calc = get_ase_calc(embedder) vib = Vibrations(atoms, name=title) if os.path.isdir(title): os.chdir(title) for f in os.listdir(): os.remove(f) os.chdir(os.path.dirname(os.getcwd())) else: os.mkdir(title) os.chdir(title) t_start = time.perf_counter() with HiddenPrints(): vib.run() # freqs = vib.get_frequencies() freqs = vib.get_energies() * 8065.544 # from eV to cm-1 if logfunction is not None: elapsed = time.perf_counter() - t_start logfunction( f'{title} - frequency calculation completed ({time_to_string(elapsed)})' ) os.chdir(os.path.dirname(os.getcwd())) return freqs, np.count_nonzero(freqs.imag > 1e-3)
def read(self, method='standard', direction='central'): """Read data from a pre-performed calculation.""" self.timer.start('read') self.timer.start('vibrations') Vibrations.read(self, method, direction) # we now have: # self.H : Hessian matrix # self.im : 1./sqrt(masses) # self.modes : Eigenmodes of the mass weighted Hessian self.om_Q = self.hnu.real # energies in eV self.om_v = self.om_Q # pre-factors for one vibrational excitation with np.errstate(divide='ignore'): self.vib01_Q = np.where(self.om_Q > 0, 1. / np.sqrt(2 * self.om_Q), 0) # -> sqrt(amu) * Angstrom self.vib01_Q *= np.sqrt(u.Ha * u._me / u._amu) * u.Bohr self.timer.stop('vibrations') self.timer.start('excitations') self.init_parallel_read() if not hasattr(self, 'ex0E_p'): if self.overlap: self.read_excitations_overlap() else: self.read_excitations() self.timer.stop('excitations') self.timer.stop('read')
def vibname(tmp_path, relaxed): atoms = relaxed.copy() atoms.calc = relaxed.calc name = str(tmp_path / 'vib') vib = Vibrations(atoms, name=name) vib.run() return name
def vibname(relaxed): atoms = relaxed.copy() atoms.calc = relaxed.calc name = 'vib' vib = Vibrations(atoms, name=name) vib.run() return name
def __init__( self, atoms, Excitations, indices=None, gsname='rraman', # name for ground state calculations exname=None, # name for excited state calculations delta=0.01, nfree=2, directions=None, exkwargs={}, # kwargs to be passed to Excitations exext='.ex.gz', # extension for Excitation names txt='-', verbose=False): assert (nfree == 2) Vibrations.__init__(self, atoms, indices, gsname, delta, nfree) self.name = gsname + '-d%.3f' % delta if exname is None: exname = gsname self.exname = exname + '-d%.3f' % delta self.exext = exext if directions is None: self.directions = np.array([0, 1, 2]) else: self.directions = np.array(directions) self.exobj = Excitations self.exkwargs = exkwargs self.timer = Timer() self.txt = get_txt(txt, rank) self.verbose = verbose
def test_Ag_Cu100(): from math import sqrt from ase import Atom, Atoms from ase.neb import NEB from ase.constraints import FixAtoms from ase.vibrations import Vibrations from ase.calculators.emt import EMT from ase.optimize import QuasiNewton, BFGS # Distance between Cu atoms on a (100) surface: d = 3.6 / sqrt(2) initial = Atoms('Cu', positions=[(0, 0, 0)], cell=(d, d, 1.0), pbc=(True, True, False)) initial *= (2, 2, 1) # 2x2 (100) surface-cell # Approximate height of Ag atom on Cu(100) surfece: h0 = 2.0 initial += Atom('Ag', (d / 2, d / 2, h0)) # Make band: images = [initial.copy() for i in range(6)] neb = NEB(images, climb=True) # Set constraints and calculator: constraint = FixAtoms(range(len(initial) - 1)) for image in images: image.calc = EMT() image.set_constraint(constraint) # Displace last image: images[-1].positions[-1] += (d, 0, 0) # Relax height of Ag atom for initial and final states: dyn1 = QuasiNewton(images[0]) dyn1.run(fmax=0.01) dyn2 = QuasiNewton(images[-1]) dyn2.run(fmax=0.01) # Interpolate positions between initial and final states: neb.interpolate() for image in images: print(image.positions[-1], image.get_potential_energy()) dyn = BFGS(neb, trajectory='mep.traj') dyn.run(fmax=0.05) for image in images: print(image.positions[-1], image.get_potential_energy()) a = images[0] vib = Vibrations(a, [4]) vib.run() print(vib.get_frequencies()) vib.summary() print(vib.get_mode(-1)) vib.write_mode(-1, nimages=20)
def test_gs_minimum(): """Test ground state minimum distance, energy and vibrational frequency""" atoms = H2Morse() assert atoms.get_distance(0, 1) == pytest.approx(Re[0], 1.e-12) assert atoms.get_potential_energy() == -De[0] # check ground state vibrations vib = Vibrations(atoms) vib.run() assert (vib.get_frequencies().real[-1] == pytest.approx(ome[0], 1e-2))
def run(self): if self.overlap: # XXXX stupid way to make a copy self.atoms.get_potential_energy() self.eq_calculator = self.atoms.get_calculator() fname = self.exname + '.eq.gpw' self.eq_calculator.write(fname, 'all') self.eq_calculator = self.eq_calculator.__class__(fname) self.eq_calculator.converge_wave_functions() Vibrations.run(self)
def VibScript(): from ase.vibrations import Vibrations import glob, json, cPickle, ase, os ####################### print "Initializing..." #---------------------- params, atoms = initialize( ) # Remove old .out/.err files, load from fw_spec, and write 'init.traj' prev = glob.glob( '*.pckl') #delete incomplete pckls - facilitating restarted jobs if rank() == 0: for p in prev: if os.stat(p).st_size < 100: os.remove(p) atoms.set_calculator(makeCalc(params)) vib = Vibrations(atoms, delta=params['delta'], indices=json.loads(params['vibids_json'])) vib.run() vib.write_jmol() ########################## print "Storing Results..." #------------------------- vib.summary(log='vibrations.txt') with open('vibrations.txt', 'r') as f: vibsummary = f.read() ase.io.write('final.traj', atoms) optAtoms = ase.io.read('final.traj') vib_energies, vib_frequencies = vib.get_energies(), vib.get_frequencies() resultDict = mergeDicts([ params, trajDetails(optAtoms), { 'vibfreqs_pckl': cPickle.dumps(vib_frequencies), 'vibsummary': vibsummary, 'vibengs_pckl': cPickle.dumps(vib_energies) } ]) with open('result.json', 'w') as outfile: outfile.write(json.dumps(resultDict)) with open('result.json', 'r') as outfile: json.loads(outfile.read()) #test that dictionary isn't 'corrupted' if rank() == 0: log(params, optAtoms) return 0
def characteriseTSinternal(self, mol): os.chdir((self.workingDir + '/Raw/' + self.procNum)) if (self.lowMeth == 'nwchem'): mol = tl.setCalc(mol, self.lowString, 'nwchem2', self.lowLev) self.Reac.get_forces() else: mol = tl.setCalc(mol, self.lowString, self.lowMeth, self.lowLev) vib = Vibrations(mol) vib.clean() vib.run() viblist = vib.get_frequencies() print("getting vibs") TSFreqs, zpe = tl.getVibString(viblist, False, True) print("vibs done " + str(zpe)) imaginaryFreq = tl.getImageFreq(viblist) vib.clean() os.chdir((self.workingDir)) # Finally get single point energy mol = tl.setCalc(mol, self.singleString, self.singleMeth, self.singleLev) print("Getting single point energy for TS = " + str(mol.get_potential_energy()) + "zpe = " + str(zpe) + "reactant energy = " + str(self.reactantEnergy)) energy = mol.get_potential_energy() + zpe return TSFreqs, imaginaryFreq, zpe, energy
def run(self): if self.overlap: # XXXX stupid way to make a copy self.atoms.get_potential_energy() calc = self.atoms.calc fname = self.exname + '.eq.gpw' calc.write(fname, 'all') self.eq_calculator = calc.__class__.read(fname) if hasattr(self.eq_calculator, 'converge_wave_functions'): self.eq_calculator.converge_wave_functions() Vibrations.run(self)
def read(self, method='standard', direction='central'): """Read data from a pre-performed calculation.""" if not hasattr(self, 'modes'): self.timer.start('read vibrations') Vibrations.read(self, method, direction) # we now have: # self.H : Hessian matrix # self.im : 1./sqrt(masses) # self.modes : Eigenmodes of the mass weighted H self.om_r = self.hnu.real # energies in eV self.timer.stop('read vibrations') if not hasattr(self, 'ex0E_p'): self.read_excitations()
def __init__(self, atoms, indices=None, name='ir', delta=0.01, nfree=2, directions=None): Vibrations.__init__(self, atoms, indices=indices, name=name, delta=delta, nfree=nfree) if atoms.constraints: print('WARNING! \n Your Atoms object is constrained. ' 'Some forces may be unintended set to zero. \n') if directions is None: self.directions = np.asarray([0, 1, 2]) else: self.directions = np.asarray(directions) self.ir = True self.ram = False
def characteriseFreqInternal(self, mol): os.chdir((self.workingDir + '/' + '/Raw/' + self.procNum)) vib = Vibrations(mol) vib.clean() vib.run() viblist = vib.get_frequencies() freqs, zpe = tl.getVibString(viblist, False, False) vib.clean() os.chdir((self.workingDir)) return freqs, zpe
def test_ideal_gas_thermo(): atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)]) atoms.calc = EMT() QuasiNewton(atoms).run(fmax=0.01) energy = atoms.get_potential_energy() vib = Vibrations(atoms, name='idealgasthermo-vib') vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=atoms, symmetrynumber=2, spin=0, potentialenergy=energy) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.)
def get_thermo_correction( self, coords: simtk.unit.quantity.Quantity) -> unit.quantity.Quantity: """ Returns the thermochemistry correction. This calls: https://wiki.fysik.dtu.dk/ase/ase/thermochemistry/thermochemistry.html and uses the Ideal gas rigid rotor harmonic oscillator approximation to calculate the Gibbs free energy correction that needs to be added to the single point energy to obtain the Gibb's free energy coords: [K][3] Raises: verror: if imaginary frequencies are detected a ValueError is raised Returns: float -- temperature correct [kT] """ if not (len(coords.shape) == 3 and coords.shape[2] == 3 and coords.shape[0] == 1): raise RuntimeError( f"Something is wrong with the shape of the provided coordinates: {coords.shape}. Only x.shape[0] == 1 is possible." ) ase_mol = copy.deepcopy(self.ase_mol) for atom, c in zip(ase_mol, coords[0]): atom.x = c[0].value_in_unit(unit.angstrom) atom.y = c[1].value_in_unit(unit.angstrom) atom.z = c[2].value_in_unit(unit.angstrom) calculator = self.model.ase() ase_mol.set_calculator(calculator) vib = Vibrations(ase_mol, name=f"/tmp/vib{random.randint(1,10000000)}") vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo( vib_energies=vib_energies, atoms=ase_mol, geometry="nonlinear", symmetrynumber=1, spin=0, ) try: G = thermo.get_gibbs_energy( temperature=temperature.value_in_unit(unit.kelvin), pressure=pressure.value_in_unit(unit.pascal), ) except ValueError as verror: logger.critical(verror) vib.clean() raise verror # removes the vib tmp files vib.clean() return ( G * eV_to_kJ_mol ) * unit.kilojoule_per_mole # eV * conversion_factor(eV to kJ/mol)
def freq(atoms=None): if atoms is None: atoms = read('md.traj',index=0) atoms.calc = IRFF(atoms=atoms,libfile='ffield.json',rcut=None,nn=True,massage=2) # Compute frequencies frequencies = Vibrations(atoms, name='freq') frequencies.run() # Print a summary frequencies.summary() frequencies.write_dos() # Write jmol file if requested # if write_jmol: frequencies.write_jmol()
def run(self): if self.overlap: # XXXX stupid way to make a copy self.atoms.get_potential_energy() self.eq_calculator = self.atoms.calc fname = 'tmp.gpw' self.eq_calculator.write(fname, 'all') self.eq_calculator = self.eq_calculator.__class__(restart=fname) try: # XXX GPAW specific self.eq_calculator.converge_wave_functions() except AttributeError: pass Vibrations.run(self)
def vib_zpe(self, job, atoms): from ase.vibrations import Vibrations self.log('-' * 60) self.log('Run ZEP calculation: {0}'.format(job)) label = os.path.join(self.label, job) label = os.path.join(label, 'vib') # copy file calculator = deepcopy(self.calculator) dip = dipole_correction(atoms, edir=3) calculator.update(dip) calculator.update({ 'calculation': 'scf', 'tstress': True, 'tprnfor': True, 'outdir': '../', 'prefix': '%s' % job, 'startingpot': 'file', 'startingwfc': 'file', 'etot_conv_thr': 1e-6, 'disk_io': 'none', }) # better to restart from previous geo_relax calculation calc = Espresso( label=label, **calculator, ) atoms.calc = calc if job[-1] == 'O': indices = [-1] elif job[-2:] == 'OH' and job[-3:] != 'OOH': indices = [-1, -2] elif job[-3:] == 'OOH': indices = [-1, -2, -3] elif job[-2:] == 'O2': indices = [-1, -2] else: indices = [] # print('%!!!') return job, 0 vib = Vibrations(atoms, name=os.path.join(label, job), indices=indices) vib.run() vib_energies = np.real(vib.get_energies()) zpe = 0. for energy in vib_energies: zpe += 0.5 * energy self.zpes[job] = zpe return job, zpe
def neural_hessian_ase(ase_atoms): print("Calculating Numerical Hessian using ASE") vib = Vibrations(ase_atoms, delta=0.05) vib.run() vib.summary() hessian = np.array(vib.H) * (kcal/mol) * Bohr**2 vib.clean() return hessian
def test_vibrations_restart_dir(self, testdir, random_dimer): vib = Vibrations(random_dimer) vib.run() freqs = vib.get_frequencies() assert freqs is not None # write/read the data from another working directory atoms = random_dimer.copy() # This copy() removes the Calculator with ase.utils.workdir('run_from_here', mkdir=True): vib = Vibrations(atoms, name=str(Path.cwd().parent / 'vib')) assert_array_almost_equal(freqs, vib.get_frequencies()) assert vib.clean() == 13
def __init__(self, atoms, vibname, minfreq=None, maxfreq=None): """Input is a atoms object and the corresponding vibrations. With minfreq and maxfreq frequencies can be excluded from the calculation""" self.atoms = atoms # V = a * v is the combined atom and xyz-index self.mm05_V = np.repeat(1.0 / np.sqrt(atoms.get_masses()), 3) self.minfreq = minfreq self.maxfreq = maxfreq self.shape = (len(self.atoms), 3) vib = Vibrations(atoms, name=vibname) self.energies = np.real(vib.get_energies(method="frederiksen")) # [eV] self.frequencies = np.real(vib.get_frequencies(method="frederiksen")) # [cm^-1] self.modes = vib.modes self.H = vib.H
def test_harmonic_vibrations(self, testdir): """Check the numerics with a trivial case: one atom in harmonic well""" rng = np.random.RandomState(42) k = rng.rand() ref_atoms = Atoms('H', positions=np.zeros([1, 3])) atoms = ref_atoms.copy() mass = atoms.get_masses()[0] atoms.calc = ForceConstantCalculator(D=np.eye(3) * k, ref=ref_atoms, f0=np.zeros((1, 3))) vib = Vibrations(atoms, name='harmonic') vib.run() vib.read() expected_energy = ( units._hbar # In J/s * np.sqrt(k # In eV/A^2 * units._e # eV -> J * units.m**2 # A^-2 -> m^-2 / mass # in amu / units._amu # amu^-1 -> kg^-1 )) / units._e # J/s -> eV/s assert np.allclose(vib.get_energies(), expected_energy)
def __init__(self, atoms, vibname, minfreq=-np.inf, maxfreq=np.inf): """Input is a atoms object and the corresponding vibrations. With minfreq and maxfreq frequencies can be excluded from the calculation""" self.atoms = atoms # V = a * v is the combined atom and xyz-index self.mm05_V = np.repeat(1. / np.sqrt(atoms.get_masses()), 3) self.minfreq = minfreq self.maxfreq = maxfreq self.shape = (len(self.atoms), 3) vib = Vibrations(atoms, name=vibname) self.energies = np.real(vib.get_energies(method='frederiksen')) # [eV] self.frequencies = np.real( vib.get_frequencies(method='frederiksen')) # [cm^-1] self.modes = vib.modes self.H = vib.H
def __init__(self, atoms, *args, **kwargs): super().__init__(atoms, *args, **kwargs) for key in ['txt', 'exext', 'exname']: kwargs.pop(key, None) kwargs['name'] = kwargs.get('name', self.name) self.vibrations = Vibrations(atoms, *args, **kwargs) self.delta = self.vibrations.delta self.indices = self.vibrations.indices
def get_modes(self,atm,freqname="vib."): for f in [f for f in os.listdir(".") if freqname in f and '.pckl' in f]: os.remove(f) new_target = open(os.devnull, "w") old_target, sys.stdout = sys.stdout, new_target atm.set_calculator(ANIENS(self.ens)) vib = Vibrations(atm, nfree=2, name=freqname) vib.run() freq = vib.get_frequencies() modes = np.stack(vib.get_mode(i) for i in range(freq.size)) vib.clean() sys.stdout = old_target return modes
def run(label, atoms): #calc.mode = 1 calc.directory = 'vib/pt/{0}'.format(label) calc.prefix = 'al2o3-pt-{0}'.format(label) calc.results = {} calc.CP2K_INPUT.FORCE_EVAL_list[0].DFT.Wfn_restart_file_name = 'al2o3-pt-{0}-RESTART.wfn'.format(label) calc.CP2K_INPUT.MOTION.CONSTRAINT.FIXED_ATOMS_list = [] #=============================================================================== atoms.set_calculator(calc) ###calc.write_input_file() #e = atoms.get_potential_energy() #t = calc.get_time() print(' {0} '.format(label)) vib = Vibrations(atoms, indices = [120]) vib.run() vib.summary() import os, shutil for file in os.listdir('.'): if "pckl" in file: shutil.move(file,calc.directory)
def test_combine(testdir): dirname = 'subdir' vibname = 'ir' with workdir(dirname, mkdir=True): atoms = molecule('C2H6') ir = Infrared(atoms) assert ir.name == vibname ir.calc = RandomCalculator() ir.run() freqs = ir.get_frequencies() ints = ir.intensities assert ir.combine() == 49 ir = Infrared(atoms) assert (freqs == ir.get_frequencies()).all() assert (ints == ir.intensities).all() vib = Vibrations(atoms, name=vibname) assert (freqs == vib.get_frequencies()).all() # Read the data from other working directory with workdir('..'): ir = Infrared(atoms, name=f'{dirname}/{vibname}') assert (freqs == ir.get_frequencies()).all() ir = Infrared(atoms) assert ir.split() == 1 assert (freqs == ir.get_frequencies()).all() assert (ints == ir.intensities).all() vib = Vibrations(atoms, name=vibname) assert (freqs == vib.get_frequencies()).all() assert ir.clean() == 49
def __init__( self, atoms, Excitations, indices=None, gsname='rraman', # name for ground state calculations exname=None, # name for excited state calculations delta=0.01, nfree=2, directions=None, approximation='Profeta', observation={'geometry': '-Z(XX)Z'}, exkwargs={}, # kwargs to be passed to Excitations exext='.ex.gz', # extension for Excitation names txt='-', verbose=False, ): assert (nfree == 2) Vibrations.__init__(self, atoms, indices, gsname, delta, nfree) self.name = gsname + '-d%.3f' % delta if exname is None: exname = gsname self.exname = exname + '-d%.3f' % delta self.exext = exext if directions is None: self.directions = np.array([0, 1, 2]) else: self.directions = np.array(directions) self.approximation = approximation self.observation = observation self.exobj = Excitations self.exkwargs = exkwargs self.timer = Timer() self.txt = convert_string_to_fd(txt) self.verbose = verbose
def test_consistency_with_vibrationsdata(self, testdir, n2_emt): atoms = n2_emt vib = Vibrations(atoms) vib.run() vib_data = vib.get_vibrations() assert_array_almost_equal(vib.get_energies(), vib_data.get_energies()) # Compare the last mode as the others may be re-ordered by negligible # energy changes assert_array_almost_equal(vib.get_mode(5), vib_data.get_modes()[5])
def test_co_vibespresso_vibrations(tmpdir): tmpdir.chdir() co = Atoms('CO', positions=[[1.19382389081, 0.0, 0.0], [0.0, 0.0, 0.0]]) co.set_cell(np.ones(3) * 12.0 * Bohr) calc = Vibespresso(pw=34.0 * Rydberg, dw=144.0 * Rydberg, kpts='gamma', xc='PBE', calculation='scf', ion_dynamics='None', spinpol=False, outdir='vibs') co.set_calculator(calc) # calculate the vibrations vib = Vibrations(co, indices=range(len(co)), delta=0.01, nfree=2) vib.run() assert np.allclose(vib.get_energies(), REF_ENE)
from ase.vibrations import Vibrations from __init__ import AnharmonicModes slab = fcc111('Al', size=(2, 2, 2), vacuum=3.0) CH3 = molecule('CH3') add_adsorbate(slab, CH3, 2.5, 'ontop') constraint = FixAtoms(mask=[a.symbol == 'Al' for a in slab]) slab.set_constraint(constraint) slab.set_calculator(EMT()) dyn = QuasiNewton(slab, logfile='/dev/null') dyn.run(fmax=0.05) vib = Vibrations(slab, indices=[8, 9, 10, 11]) vib.run() vib.summary(log='/dev/null') vib.clean() AM = AnharmonicModes(vibrations_object=vib) rot_mode = AM.define_rotation( basepos=[0., 0., -1.], branch=[9, 10, 11], symnumber=3) AM.run() AM.summary(log='/dev/null') AM.clean() # print(AM.get_ZPE(), AM.get_entropic_energy())
#!/usr/bin/env python from ase.db import connect from ase.calculators.aims import Aims from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms from ase import Atoms, Atom from ase.io.aims import read_aims from ase.optimize import BFGS from ase.vibrations import Vibrations mydb = connect("mydb.db") atoms = mydb.get_atoms(name='pt-co-relax') calc = Aims(label='cluster/pt-co-vib-cons', xc='pbe', spin='none', relativistic = 'atomic_zora scalar', sc_accuracy_etot=1e-7, sc_accuracy_eev=1e-3, sc_accuracy_rho=1e-4, sc_accuracy_forces=1e-3) atoms.set_calculator(calc) vib = Vibrations(atoms, indices=[1, 2], name='cluster/pt-co-vib-cons/vib') vib.run() vib.summary()
H 5.320549047980879 3.220584852467720 3.974551561510350 H 7.723359150977955 3.224855971783890 4.574146712279462 H 7.580803493981530 5.034479218283977 4.877211530909463 """ h = 0.3 atoms = Cluster(read_xyz(StringIO.StringIO(butadiene))) atoms.minimal_box(3.0, h) atoms.set_calculator(GPAW(h=h)) if 0: dyn = FIRE(atoms) dyn.run(fmax=0.05) atoms.write("butadiene.xyz") vibname = "fcvib" vib = Vibrations(atoms, name=vibname) vib.run() # Modul a = FranckCondon(atoms, vibname, minfreq=250) # excited state forces F = np.array( [ [-2.11413, 0.07317, -0.91682], [3.23569, -0.74520, 0.76758], [-3.44847, 0.63846, -0.81080], [2.77345, 0.01272, 0.74811], [-0.06544, -0.01078, -0.03209], [-0.01245, -0.01123, -0.00040], [0.00186, -0.05864, -0.00371],
from __future__ import print_function from ase import Atoms from ase.calculators.emt import EMT from ase.optimize import QuasiNewton from ase.vibrations import Vibrations from ase.thermochemistry import IdealGasThermo n2 = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(n2).run(fmax=0.01) vib = Vibrations(n2) vib.run() print(vib.get_frequencies()) vib.summary() print(vib.get_mode(-1)) vib.write_mode(n=None, nimages=20) vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=n2, symmetrynumber=2, spin=0) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.) assert vib.clean(empty_files=True) == 0 assert vib.clean() == 13
from ase.build import bulk from ase.constraints import FixAtoms from ase.optimize import QuasiNewton from ase.vibrations import Vibrations from ase.phonons import Phonons from ase.thermochemistry import (IdealGasThermo, HarmonicThermo, CrystalThermo) from ase.calculators.emt import EMT # Ideal gas thermo. atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(atoms).run(fmax=0.01) energy = atoms.get_potential_energy() vib = Vibrations(atoms, name='idealgasthermo-vib') vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=atoms, symmetrynumber=2, spin=0, potentialenergy=energy) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.) # Harmonic thermo. atoms = fcc100('Cu', (2, 2, 2), vacuum=10.) atoms.set_calculator(EMT()) add_adsorbate(atoms, 'Pt', 1.5, 'hollow') atoms.set_constraint(FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == 'Cu']))
# the valence electrons sigma=0.1, psppath='/home/vossj/suncat/psp/gbrv1.5pbe', # pseudopotential convergence={'energy': 1e-5, 'mixing': 0.1, 'nmix': 10, 'mix': 4, 'maxsteps': 500, 'diag': 'david' }, # convergence parameters outdirprefix='calcdirv') # output directory for Quantum Espresso files atoms.set_calculator(calcvib) vib = Vibrations(atoms, indices=vibrateatoms, delta=0.03) vib.run() vib.summary(method='standard') # Make trajectory files to visualize the modes. for mode in range(len(vibrateatoms) * 3): vib.write_mode(mode) # Calculate free energy vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, electronicenergy=energy, atoms=atoms, geometry='linear', symmetrynumber=2, spin=0)
# name of output file for free energies output_name = 'out.energy' ### At 300K and 101325 Pa ### change for your operating conditions T = 300 # K P = 101325 # Pa ######################################################################################################### ##### END ##### ######################################################################################################### energy = atoms.get_potential_energy() # caclulate the energy, to be used to determine G vibrateatoms = [atom.index for atom in atoms if atom.symbol in ['H','N']] # calculate the vibrational modes for all N and H atoms # Calculate vibrations vib = Vibrations(atoms,indices=vibrateatoms,delta=0.03) # define a vibration calculation vib.run() # run the vibration calculation vib.summary(method='standard') # summarize the calculated results for mode in range(len(vibrateatoms)*3): # Make trajectory files to visualize the modes. vib.write_mode(mode) vibenergies=vib.get_energies() vibenergies=[vib for vib in vibenergies if not isinstance(vib,complex)] # only take the real modes gibbs = HarmonicThermo(vib_energies = vibenergies, electronicenergy = energy) freeenergy = gibbs.get_gibbs_energy(T,P) f=open(output_name,'w') f.write('Potential energy: '+str(energy)+'\n'+'Free energy: '+str(freeenergy)+'\n') f.close
calc = espresso(pw = 500., dw = 5000., nbands = -10, kpts=(1, 1, 1), xc = 'BEEF', outdir='outdir', psppath = "/scratch/users/colinfd/psp/gbrv", sigma = 10e-4) atoms.set_calculator(calc) dyn = QuasiNewton(atoms,logfile='out.log',trajectory='out.traj') dyn.run(fmax=0.01) electronicenergy = atoms.get_potential_energy() vib = Vibrations(atoms) # run vibrations on all atoms vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, electronicenergy=electronicenergy, atoms=atoms, geometry='linear', # linear/nonlinear symmetrynumber=2, spin=0) # symmetry numbers from point group G = thermo.get_free_energy(temperature=300, pressure=101325.) # vapor pressure of water at room temperature e = open('e_energy.out','w') g = open('g_energy.out','w') e.write(str(electronicenergy)) g.write(str(G))
def calculate(element, ref_data, p): values_dict = {} values_dict[p['xc']] = {} for XY, data in ref_data[p['xc']].items(): X = XY.split('-')[0] Y = XY.split('-')[1] if (X == Y and X == element) or (X != Y and (X == element or Y == element)): # compound contains the requested element re_ref = data['re'] we_ref = data['we'] m0_ref = data.get('m0', 0.0) # compound = Atoms(X+Y, [ (0, 0, 0.5 ), (0, 0, 0.5+re_ref/a), ], pbc=0) compound.set_cell([a, b, c], scale_atoms=1) compound.center() # calculation on the reference geometry calc = Calculator(**p) compound.set_calculator(calc) e_compound = compound.get_potential_energy() finegd = calc.density.finegd dip = finegd.calculate_dipole_moment(calc.density.rhot_g)*calc.a0 vib = Vibrations(compound) vib.run() vib_compound = vib.get_frequencies(method='frederiksen').real[-1] world.barrier() vib_pckl = glob('vib.*.pckl') if rank == 0: for file in vib_pckl: remove(file) # calculation on the relaxed geometry qn = QuasiNewton(compound) #qn.attach(PickleTrajectory('compound.traj', 'w', compound).write) qn.run(fmax=0.05) e_compound_r = compound.get_potential_energy() dist_compound_r = compound.get_distance(0,1) dip_r = finegd.calculate_dipole_moment(calc.density.rhot_g)*calc.a0 vib = Vibrations(compound) vib.run() vib_compound_r = vib.get_frequencies(method='frederiksen').real[-1] world.barrier() vib_pckl = glob('vib.*.pckl') if rank == 0: for file in vib_pckl: remove(file) del compound e = e_compound we = vib_compound m0 = dip e_r = e_compound_r we_r = vib_compound_r re_r = dist_compound_r m0_r = dip_r # values_dict[p['xc']][XY] = {'re': re_r, 'we': (we_r, we), 'm0': (m0_r, m0)} # return values_dict
#!/usr/bin/env python from ase import Atom, Atoms from ase.structure import molecule from ase.calculators.cp2k import CP2K from ase.optimize import BFGS from ase.vibrations import Vibrations from multiprocessing import Pool import os atoms = molecule('CO') atoms.center(vacuum=2.0) calc = CP2K(label = 'molecules/co/vib', xc='PBE') atoms.set_calculator(calc) gopt = BFGS(atoms, logfile=None) gopt.run(fmax=1e-2) e = atoms.get_potential_energy() pos = atoms.get_positions() d = ((pos[0] - pos[1])**2).sum()**0.5 print('{0:1.4f} {1:1.4f} '.format( e, d)) vib = Vibrations(n2) vib.run() vib.summary() vib.write_mode(-1)
grid='nodisk', tolerances='tight', maxiter=777, convergence={'lshift': 0.0}, basis=basis, basispar='spherical', direct='noio', raw='set int:txs:limxmem 134217728\nmemory total 8000 Mb noverify\n', label=label) atoms.set_calculator(calc) t = time.time() if len(atoms) > 1: # need a copy of atoms for calculation of vibrations vibatoms = atoms.copy() vibatoms.set_calculator(calc) vib = Vibrations(vibatoms, name=label + '_fixed') vib.run() f = vib.get_frequencies()[-1].real # clean nwchem restart if os.path.exists(name + '_' + code + '.db'): os.remove(name + '_' + code + '.db') atoms.get_potential_energy() c.write(atoms, name=name, relaxed=False, basis=basis, frequency=f, time=time.time()-t) else: atoms.get_potential_energy() c.write(atoms, name=name, relaxed=False, basis=basis, time=time.time()-t) if len(atoms) > 1: opt = BFGS(atoms,
from ase import * from ase.vibrations import Vibrations n2 = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(n2).run(fmax=0.01) vib = Vibrations(n2) vib.run() print vib.get_frequencies() vib.summary() print vib.get_mode(-1) vib.write_mode(-1, nimages=20)
from ase import Atoms from ase.calculators.emt import EMT from ase.optimize import QuasiNewton from ase.vibrations import Vibrations from ase.thermochemistry import IdealGasThermo n2 = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(n2).run(fmax=0.01) vib = Vibrations(n2) vib.run() print(vib.get_frequencies()) vib.summary() print(vib.get_mode(-1)) vib.write_mode(n=None, nimages=20) vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=n2, symmetrynumber=2, spin=0) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.)
sys.path.append("..") from __init__ import AnharmonicModes slab = fcc111('Au', size=(2, 2, 2), vacuum=4.0) H = molecule('H') add_adsorbate(slab, H, 3.0, 'ontop') constraint = FixAtoms(mask=[a.symbol == 'Au' for a in slab]) slab.set_constraint(constraint) slab.set_calculator(EMT()) QuasiNewton(slab).run(fmax=0.001) vib = Vibrations(slab, indices=[8]) vib.run() vib.summary() vib.clean() AM = AnharmonicModes( vibrations_object=vib, settings={ 'plot_mode': True, }) for i in range(len(vib.hnu)): AM.define_vibration(mode_number=-1) AM.inspect_anmodes() AM.run()
import os from ase.vibrations import Vibrations from gpaw import GPAW from gpaw.mpi import world h2o = GPAW('h2o.gpw', txt=None).get_atoms() # Test restart: vib = Vibrations(h2o) vib.run() vib.summary(method='frederiksen') # Remove a displacement file and redo it: if world.rank == 0: os.remove('vib.1z-.pckl') world.barrier() vib = Vibrations(h2o) vib.run() vib.summary(method='frederiksen')
"""Calculate the vibrational modes of a H2O molecule.""" from ase.vibrations import Vibrations from gpaw import GPAW h2o = GPAW('h2o.gpw', txt=None).get_atoms() # Create vibration calculator vib = Vibrations(h2o) vib.run() vib.summary(method='frederiksen') # Make trajectory files to visualize normal modes: for mode in range(9): vib.write_mode(mode)