Пример #1
0
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)
Пример #2
0
def test_vib():
    import os
    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()
    freqs = vib.get_frequencies()
    print(freqs)
    vib.summary()
    print(vib.get_mode(-1))
    vib.write_mode(n=None, nimages=20)
    vib_energies = vib.get_energies()

    for image in vib.iterimages():
        assert len(image) == 2

    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
    assert len(list(vib.iterimages())) == 13

    d = dict(vib.iterdisplace(inplace=False))

    for name, atoms in vib.iterdisplace(inplace=True):
        assert d[name] == atoms

    vib = Vibrations(n2)
    vib.run()
    assert vib.combine() == 13
    assert (freqs == vib.get_frequencies()).all()

    vib = Vibrations(n2)
    assert vib.split() == 1
    assert (freqs == vib.get_frequencies()).all()

    assert vib.combine() == 13
    # Read the data from other working directory
    dirname = os.path.basename(os.getcwd())
    os.chdir('..')  # Change working directory
    vib = Vibrations(n2, name=os.path.join(dirname, 'vib'))
    assert (freqs == vib.get_frequencies()).all()
    assert vib.clean() == 1
Пример #3
0
    def test_vibrations_methods(self, testdir, random_dimer):
        vib = Vibrations(random_dimer)
        vib.run()
        vib_energies = vib.get_energies()

        for image in vib.iterimages():
            assert len(image) == 2

        thermo = IdealGasThermo(vib_energies=vib_energies,
                                geometry='linear',
                                atoms=vib.atoms,
                                symmetrynumber=2,
                                spin=0)
        thermo.get_gibbs_energy(temperature=298.15,
                                pressure=2 * 101325.,
                                verbose=False)

        with open(self.logfile, 'w') as fd:
            vib.summary(log=fd)

        with open(self.logfile, 'rt') as fd:
            log_txt = fd.read()
            assert log_txt == '\n'.join(
                VibrationsData._tabulate_from_energies(vib_energies)) + '\n'

        last_mode = vib.get_mode(-1)
        scale = 0.5
        assert_array_almost_equal(
            vib.show_as_force(-1, scale=scale, show=False).get_forces(),
            last_mode * 3 * len(vib.atoms) * scale)

        vib.write_mode(n=3, nimages=5)
        for i in range(3):
            assert not Path('vib.{}.traj'.format(i)).is_file()
        mode_traj = ase.io.read('vib.3.traj', index=':')
        assert len(mode_traj) == 5

        assert_array_almost_equal(mode_traj[0].get_all_distances(),
                                  random_dimer.get_all_distances())
        with pytest.raises(AssertionError):
            assert_array_almost_equal(mode_traj[4].get_all_distances(),
                                      random_dimer.get_all_distances())

        assert vib.clean(empty_files=True) == 0
        assert vib.clean() == 13
        assert len(list(vib.iterimages())) == 13

        d = dict(vib.iterdisplace(inplace=False))

        for name, image in vib.iterdisplace(inplace=True):
            assert d[name] == random_dimer
Пример #4
0
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()

for image in vib.iterimages():
    assert len(image) == 2

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
assert len(list(vib.iterimages())) == 13

d = dict(vib.iterdisplace(inplace=False))
Пример #5
0
        '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)

# At 300K and 101325 Pa
# change for your operating conditions
freeenergy = thermo.get_gibbs_energy(temperature=300, pressure=101325)

f = open(name + '.energy', 'w')
Пример #6
0
    ediff=1e-8,
    ediffg=-0.01,
    algo="Fast",
    gga="RP",
    xc="PBE",
    kpts=(4, 4, 1),
    #		isif = 0,
    #		ibrion = 5,
    #		nsw = 0,
    #		nfree = 2
)

adsorbedH.set_calculator(calc)
electronicenergy = adsorbedH.get_potential_energy()

print("electronic energy is %.5f" % electronicenergy)

vib = Vibrations(adsorbedH, indices=[23], delta=0.01, nfree=2)
vib.run()
print(vib.get_frequencies())
vib.summary()
print(vib.get_mode(-1))
vib.write_mode(-1)
vib_energies = vib.get_energies()

thermo = HarmonicThermo(vib_energies=vib_energies,
                        electronicenergy=electronicenergy)
thermo.get_entropy(temperature=298.15)
thermo.get_internal_energy(temperature=298.15)
thermo.get_free_energy(temperature=298.15)
# 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
Пример #8
0
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)
Пример #9
0
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(-1, nimages=20)
vib_energies = vib.get_energies()

thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', 
                        atoms=n2, symmetrynumber=2, spin=0)
thermo.get_free_energy(temperature=298.15, pressure=2*101325.)
Пример #10
0
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.)
Пример #11
0
    def test_vibrations(self, testdir, n2_emt, n2_optimized):
        atoms = n2_emt
        vib = Vibrations(atoms)
        vib.run()
        freqs = vib.get_frequencies()
        vib.write_mode(n=None, nimages=5)
        vib.write_jmol()
        vib_energies = vib.get_energies()

        for image in vib.iterimages():
            assert len(image) == 2

        thermo = IdealGasThermo(vib_energies=vib_energies,
                                geometry='linear',
                                atoms=atoms,
                                symmetrynumber=2,
                                spin=0)
        thermo.get_gibbs_energy(temperature=298.15,
                                pressure=2 * 101325.,
                                verbose=False)

        vib.summary(log=self.logfile)
        with open(self.logfile, 'rt') as f:
            log_txt = f.read()
            assert log_txt == vibrations_n2_log

        mode1 = vib.get_mode(-1)
        assert_array_almost_equal(mode1,
                                  [[0., 0., -0.188935], [0., 0., 0.188935]])

        assert_array_almost_equal(
            vib.show_as_force(-1, show=False).get_forces(),
            [[0., 0., -2.26722e-1], [0., 0., 2.26722e-1]])

        for i in range(3):
            assert not os.path.isfile('vib.{}.traj'.format(i))
        mode_traj = ase.io.read('vib.3.traj', index=':')
        assert len(mode_traj) == 5
        assert_array_almost_equal(mode_traj[0].get_all_distances(),
                                  atoms.get_all_distances())
        with pytest.raises(AssertionError):
            assert_array_almost_equal(mode_traj[4].get_all_distances(),
                                      atoms.get_all_distances())

        with open('vib.xyz', 'rt') as f:
            jmol_txt = f.read()
            assert jmol_txt == jmol_txt_ref

        assert vib.clean(empty_files=True) == 0
        assert vib.clean() == 13
        assert len(list(vib.iterimages())) == 13

        d = dict(vib.iterdisplace(inplace=False))

        for name, image in vib.iterdisplace(inplace=True):
            assert d[name] == atoms

        atoms2 = n2_emt
        vib2 = Vibrations(atoms2)
        vib2.run()

        assert_array_almost_equal(freqs, vib.get_frequencies())

        # write/read the data from another working directory
        atoms3 = n2_optimized.copy()  # No calculator needed!

        workdir = os.path.abspath(os.path.curdir)
        try:
            os.mkdir('run_from_here')
            os.chdir('run_from_here')
            vib = Vibrations(atoms3, name=os.path.join(os.pardir, 'vib'))
            assert_array_almost_equal(freqs, vib.get_frequencies())
            assert vib.clean() == 13
        finally:
            os.chdir(workdir)
            if os.path.isdir('run_from_here'):
                os.rmdir('run_from_here')
Пример #12
0
from ase.vibrations import Vibrations

Au = read('CONTCAR')
indices = [8, 9, 10, 12, 13]

# Au.pbc = True
calc4 = Vasp(
    xc='PBE',  #Level of theory (density functional)
    encut=
    400,  #plane-wave kinetic energy cutoff (convergence test; I usually use about 520)
    kpts=[
        4, 4, 1
    ],  #number of k-points, e.g. [3,3,3] (convergence test; fewer kpoints are needed if lattice dimension is large)
    # isif=2, #relaxation method (2 = positions, 3 = positions+volume)
    prec='Accurate',  #accuracy (don't change this)
    sigma=0.01,  #don't need to change (smearing width)
    ismear=0,  #don't need to change (smearing method)
    isym=0,  #disables symmetry
    # ediffg=-0.03, #force tolerance, |ediffg| (eV/A) (I generally use 0.01 --> 0.03; lower is better but will take longer)
    # nsw=1000, #maximum number of steps
    ivdw=12,  #enable van der Waals interactions
    setups='recommended')
# ibrion=2) #geom opt algorithm (dont need change; default is conjugate gradient -- works fine)

Au.set_calculator(calc4)
vib = Vibrations(Au, indices=indices)
vib.run()
vib.summary()
vib.write_mode()
# Au.get_potential_energy()
Пример #13
0
# kpts={repeats},
# jobs_args='-nk {n_kpts}',

balsamcalc_module = __import__('pynta.balsamcalc',
                               fromlist=[socket_calculator])
sock_calc = getattr(balsamcalc_module, socket_calculator)

atoms.calc = sock_calc(workflow='QE_Socket',
                       job_kwargs=balsam_exe_settings,
                       **calc_keywords)

atoms.calc.set(**extra_calc_keywords)

# start vibrations calculations
vib = Vibrations(atoms, indices=indices, name=vib_files_loc)
vib.run()
vib.summary()
# vib.clean()

# write the first vibration mode to vib.0.traj file (default) - imaginary freq
vib.write_mode(n=n, nimages=nimages)

end = datetime.datetime.now()

with open(os.path.join(prefix, geom[:-10] + '_time.log'), 'a+') as f:
    f.write(str(end))
    f.write("\n")
    f.write(str(end - start))
    f.write("\n")
    f.close()
Пример #14
0
#!/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)

CH3 = molecule('CH3')
add_adsorbate(slab, CH3, 3.0, 'ontop')

constraint = FixAtoms(mask=[a.symbol == 'Al' for a in slab])
slab.set_constraint(constraint)

slab.set_calculator(EMT())

dyn = QuasiNewton(slab, trajectory='relax.traj')
dyn.run(fmax=0.01)

vib = Vibrations(slab, indices=[8, 9, 10, 11])
vib.run()
vib.summary()
vib.write_mode()

print('\n >> Anharmonics <<\n')

AM = AnharmonicModes(
    vibrations_object=vib,
    pre_names='an_mode_',
    settings={
        'use_forces': True,
        # 'plot_mode': True,
        'temperature': 298.15,
        # 'rot_nsamples': 15,
        # 'max_step_iterations': 1,
        # 'min_step_iterations': 1,
        'plot_mode_each_iteration': True,
        # 'rot_nsamples': 9,
Пример #16
0
    def vibrate(self, atoms: Atoms, indices: list, read_only=False):
        '''

        This method uses ase.vibrations module, see more for info.
        User provides the FHI-aims parameters, the Atoms object and list
        of indices of atoms to be vibrated. Variables related to FHI-aims are governed by the React object.
        Calculation folders are generated automatically and a sockets calculator is used for efficiency.

        Work in progress

        Args:
            atoms: Atoms object
            indices: list
                List of indices of atoms that require vibrations
            read_only: bool
                Flag for postprocessing - if True, the method only extracts information from existing files,
                no calculations are performed

        Returns:
            Zero-Point Energy: float
        '''
        '''Retrieve common properties'''
        basis_set = self.basis_set
        hpc = self.hpc
        params = self.params
        parent_dir = os.getcwd()
        dimensions = sum(atoms.pbc)

        if not self.filename:
            '''develop a naming scheme based on chemical formula'''
            self.filename = atoms.get_chemical_formula()

        vib_dir = parent_dir + "/VibData_" + self.filename + "/Vibs"
        print(vib_dir)

        vib = Vibrations(atoms, indices=indices, name=vib_dir)
        '''If a calculation was terminated prematurely (e.g. time limit) empty .json files remain and the calculation
        of the corresponding stretch modes would be skipped on restart. The line below prevents this'''
        vib.clean(empty_files=True)
        '''Extract vibration data from existing files'''
        if read_only:
            vib.read()

        else:
            '''Calculate required vibration modes'''
            required_cache = [
                os.path.join(vib_dir, "cache." + str(x) + y + ".json")
                for x in indices
                for y in ["x+", "x-", "y+", "y-", "y-", "z+", "z-"]
            ]
            check_required_modes_files = np.array(
                [os.path.exists(file) for file in required_cache])

            if np.all(check_required_modes_files == True):
                vib.read()
            else:
                '''Set the environment variables for geometry optimisation'''
                set_aims_command(hpc=hpc,
                                 basis_set=basis_set,
                                 defaults=2020,
                                 nodes_per_instance=self.nodes_per_instance)
                '''Generate a unique folder for aims calculation'''
                counter, subdirectory_name = self._restart_setup(
                    "Vib",
                    filename=self.filename,
                    restart=False,
                    verbose=False)

                os.makedirs(subdirectory_name, exist_ok=True)
                os.chdir(subdirectory_name)
                '''Name the aims output file'''
                out = str(counter) + "_" + str(self.filename) + ".out"
                '''Calculate vibrations and write the in a separate directory'''
                with _calc_generator(params, out_fn=out,
                                     dimensions=dimensions)[0] as calculator:
                    if not self.dry_run:
                        atoms.calc = calculator
                    else:
                        atoms.calc = EMT()

                    vib = Vibrations(atoms, indices=indices, name=vib_dir)
                    vib.run()

            vib.summary()
        '''Generate a unique folder for aims calculation'''
        if not read_only:
            os.chdir(vib_dir)
            vib.write_mode()
        os.chdir(parent_dir)

        return vib.get_zero_point_energy()