Example #1
0
def test_singlepointcalc():
    """This test makes sure that the forces returned from a
    SinglePointCalculator are immutable. Previously, successive calls to
    atoms.get_forces(apply_constraint=x), with x alternating between True and
    False, would get locked into the constrained variation."""
    def check_forces():
        """Makes sure the unconstrained forces stay that way."""
        forces = atoms.get_forces(apply_constraint=False)
        funconstrained = float(forces[0, 0])

        forces = atoms.get_forces(apply_constraint=True)

        forces = atoms.get_forces(apply_constraint=False)
        funconstrained2 = float(forces[0, 0])

        assert funconstrained2 == funconstrained

    atoms = fcc111('Cu', (2, 2, 1), vacuum=10.)
    atoms[0].x += 0.2
    atoms.set_constraint(FixAtoms(indices=[atom.index for atom in atoms]))

    # First run the tes with EMT and save a force component.
    atoms.calc = EMT()
    check_forces()
    f = float(atoms.get_forces(apply_constraint=False)[0, 0])

    # Save and reload with a SinglePointCalculator.
    atoms.write('singlepointtest.traj')
    atoms = read('singlepointtest.traj')
    check_forces()

    # Manually change a value.
    forces = atoms.get_forces(apply_constraint=False)
    forces[0, 0] = 42.
    forces = atoms.get_forces(apply_constraint=False)
    assert forces[0, 0] == f
Example #2
0
def run_md_Morse(Morse_parameters, A0, steps=10000, trajectory="md.traj"):
    hbar_fs = (ase.units._hbar / ase.units._e) * 1.E15
    D, a, R0, frequency = Morse_parameters[0:4]
    r0 = R0
    calculator = MorsePotential2(a=a, D=D, r0=r0)
    #calculator = MorsePotential(rho0=6.0, epsilon=2.0, r0=1.0)
    period = (hbar_fs / frequency) / (2 * pi)
    pos = 1 * (r0 + A0)
    atoms = Atoms("HH", positions=[[0, 0, 0], [pos, 0, 0]], masses=[1.0, 1.0])
    constr = FixAtoms(indices=[0])
    atoms.set_constraint(constr)
    atoms.set_calculator(calculator)
    #    def V(d):
    #        atoms.set_positions([[0,0,0],[d,0,0]])
    #        return atoms.get_potential_energy()
    #    r_plot = linspace(-4.0,4.0,1000)
    #    V_plot = array([V(d) for d in r_plot])
    #    plt.plot(r_plot,V_plot)
    #    plt.show()

    dynamics = VelocityVerlet(atoms,
                              dt=(period / 20.) * ase.units.fs,
                              trajectory=trajectory)
    dynamics.run(20000)
Example #3
0
def construct_geometries(parent_calc, ml2relax):
    counter_calc = parent_calc
    # Initial structure guess
    initial_slab = fcc100("Cu", size=(2, 2, 3))
    add_adsorbate(initial_slab, "C", 1.7, "hollow")
    initial_slab.center(axis=2, vacuum=4.0)
    mask = [atom.tag > 1 for atom in initial_slab]
    initial_slab.set_constraint(FixAtoms(mask=mask))
    initial_slab.set_pbc(True)
    initial_slab.wrap(pbc=[True] * 3)
    initial_slab.set_calculator(counter_calc)

    # Final structure guess
    final_slab = initial_slab.copy()
    final_slab[-1].x += final_slab.get_cell()[0, 0] / 3
    final_slab.set_calculator(counter_calc)
    if not ml2relax:
        print("BUILDING INITIAL")
        qn = BFGS(
            initial_slab, trajectory="initial.traj", logfile="initial_relax_log.txt"
        )
        qn.run(fmax=0.01, steps=100)
        print("BUILDING FINAL")
        qn = BFGS(final_slab, trajectory="final.traj", logfile="final_relax_log.txt")
        qn.run(fmax=0.01, steps=100)
        initial_slab = read("initial.traj", "-1")
        final_slab = read("final.traj", "-1")
        # If there is already a pre-existing initial and final relaxed parent state we can read that to use as a starting point
        # initial_slab = read("/content/parent_initial.traj")
        # final_slab = read("/content/parent_final.traj")
    else:
        initial_slab = initial_slab
        final_slab = final_slab

    # initial_force_calls = counter_calc.force_calls
    return initial_slab, final_slab  # , initial_force_calls
def test_dftb_relax_surface():
    import os
    from ase.test import require
    from ase.test.testsuite import datafiles_directory
    from ase.build import diamond100
    from ase.calculators.dftb import Dftb
    from ase.optimize import BFGS
    from ase.constraints import FixAtoms

    require('dftb')

    os.environ['DFTB_PREFIX'] = datafiles_directory

    calc = Dftb(
        label='dftb',
        kpts=(2, 2, 1),
        Hamiltonian_SCC='Yes',
        Hamiltonian_Filling='Fermi {',
        Hamiltonian_Filling_empty='Temperature [Kelvin] = 500.0',
    )

    a = 5.40632280995384
    atoms = diamond100('Si', (1, 1, 6),
                       a=a,
                       vacuum=6.,
                       orthogonal=True,
                       periodic=True)
    atoms.positions[-2:, 2] -= 0.2
    atoms.set_constraint(FixAtoms(indices=range(4)))
    atoms.set_calculator(calc)

    dyn = BFGS(atoms, logfile='-')
    dyn.run(fmax=0.1)

    e = atoms.get_potential_energy()
    assert abs(e - -214.036907) < 1., e
Example #5
0
def test_replay():
    from math import sqrt
    from ase import Atoms, Atom
    from ase.constraints import FixAtoms
    from ase.calculators.emt import EMT
    from ase.optimize import QuasiNewton
    from ase.io import read
    from ase.visualize import view

    # Distance between Cu atoms on a (100) surface:
    d = 3.6 / sqrt(2)
    a = Atoms('Cu',
              positions=[(0, 0, 0)],
              cell=(d, d, 1.0),
              pbc=(True, True, False))
    a *= (2, 2, 1)  # 2x2 (100) surface-cell

    # Approximate height of Ag atom on Cu(100) surfece:
    h0 = 2.0
    a += Atom('Ag', (d / 2, d / 2, h0))

    if 0:
        view(a)

    constraint = FixAtoms(range(len(a) - 1))
    a.calc = EMT()
    a.set_constraint(constraint)
    dyn1 = QuasiNewton(a, trajectory='AgCu1.traj', logfile='AgCu1.log')
    dyn1.run(fmax=0.1)

    a = read('AgCu1.traj')
    a.calc = EMT()
    print(a.constraints)
    dyn2 = QuasiNewton(a, trajectory='AgCu2.traj', logfile='AgCu2.log')
    dyn2.replay_trajectory('AgCu1.traj')
    dyn2.run(fmax=0.01)
Example #6
0
    def get_atoms(self, frame, remove_hidden=False):
        atoms = Atoms(positions=self.P[frame],
                      numbers=self.Z,
                      magmoms=self.M[0],
                      tags=self.T[frame],
                      cell=self.A[frame],
                      pbc=self.pbc)

        if not np.isnan(self.V).any():
            atoms.set_velocities(self.V[frame])

        # check for constrained atoms and add them accordingly:
        if not self.dynamic.all():
            atoms.set_constraint(FixAtoms(mask=1 - self.dynamic))

        # Remove hidden atoms if applicable
        if remove_hidden:
            atoms = atoms[self.visible]
            f = self.F[frame][self.visible]
        else:
            f = self.F[frame]
        atoms.set_calculator(
            SinglePointCalculator(atoms, energy=self.E[frame], forces=f))
        return atoms
Example #7
0
def slabgen(termination, size, adsorbate, position):
    if termination == '100':
        prim = fcc100('Cu',
                      a=3.6302862146117354,
                      size=(1, 1, 5),
                      vacuum=15,
                      orthogonal=True,
                      periodic=True)
    elif termination == '111':
        prim = fcc111_root('Cu',
                           root=3,
                           a=3.6302862146117354,
                           size=(1, 1, 5),
                           vacuum=15)

    super = make_supercell(prim, size)
    add_adsorbate(slab=super,
                  adsorbate=adsorbate,
                  height=ads_height,
                  position=position)
    constr = FixAtoms(
        indices=[atom.index for atom in super if atom.position[2] < 19])
    super.set_constraint(constr)
    return super
Example #8
0
    def optimize(self, atoms, name):
        opts = self.opts
        if opts.constrain_tags:
            tags = [int(t) for t in opts.constrain_tags.split(',')]
            mask = [t in tags for t in atoms.get_tags()]
            atoms.constraints = FixAtoms(mask=mask)
        
        trajectory = PickleTrajectory(self.get_filename(name, 'traj'), 'w',
                                      atoms)
        if opts.maximum_stress:
            optimizer = LBFGS(UnitCellFilter(atoms), logfile=self.logfile)
            fmax = opts.maximum_stress
        else:
            optimizer = LBFGS(atoms, logfile=self.logfile)
            fmax = opts.maximum_force

        optimizer.attach(trajectory)
        optimizer.run(fmax=fmax)

        data = {}
        if hasattr(optimizer, 'force_calls'):
            data['force_calls'] = optimizer.force_calls

        return data
Example #9
0
def test_dftb_relax_surface(factory):
    calc = factory.calc(
        label='dftb',
        kpts=(2, 2, 1),
        Hamiltonian_SCC='Yes',
        Hamiltonian_Filling='Fermi {',
        Hamiltonian_Filling_empty='Temperature [Kelvin] = 500.0',
    )

    a = 5.40632280995384
    atoms = diamond100('Si', (1, 1, 6),
                       a=a,
                       vacuum=6.,
                       orthogonal=True,
                       periodic=True)
    atoms.positions[-2:, 2] -= 0.2
    atoms.set_constraint(FixAtoms(indices=range(4)))
    atoms.calc = calc

    dyn = BFGS(atoms, logfile='-')
    dyn.run(fmax=0.1)

    e = atoms.get_potential_energy()
    assert abs(e - -214.036907) < 1., e
Example #10
0
def aual100(site, height, calc=None):
    slab = fcc100('Al', size=(2, 2, 2))
    slab.center(axis=2, vacuum=3.0)
    add_adsorbate(slab, 'Au', height, site)
    mask = [atom.symbol == 'Al' for atom in slab]
    fixlayer = FixAtoms(mask=mask)
    slab.set_constraint(fixlayer)

    if calc is None:
        calc = GPAW(mode=PW(200),
                    kpts=(2, 2, 1),
                    xc='PBE',
                    txt=site + '.txt',
                    eigensolver='rmm-diis',
                    nbands=40)

    slab.set_calculator(calc)
    qn = QuasiNewton(slab, trajectory=site + calc.name + '.traj')
    qn.run(fmax=0.05)

    if isinstance(calc, GPAW):
        calc.write(site + '.gpw')

    return slab.get_potential_energy()
Example #11
0
def read_aims(filename):
    """Import FHI-aims geometry type files.

    Reads unitcell, atom positions and constraints from
    a geometry.in file.
    """

    from ase import Atoms
    from ase.constraints import FixAtoms, FixCartesian
    import numpy as np

    atoms = Atoms()
    fd = open(filename, 'r')
    lines = fd.readlines()
    fd.close()
    positions = []
    cell = []
    symbols = []
    magmoms = []
    fix = []
    fix_cart = []
    xyz = np.array([0, 0, 0])
    i = -1
    n_periodic = -1
    periodic = np.array([False, False, False])
    cart_positions, scaled_positions = False, False
    for n, line in enumerate(lines):
        inp = line.split()
        if inp == []:
            continue
        if inp[0] == 'atom':
            cart_positions = True
            if xyz.all():
                fix.append(i)
            elif xyz.any():
                fix_cart.append(FixCartesian(i, xyz))
            floatvect = float(inp[1]), float(inp[2]), float(inp[3])
            positions.append(floatvect)
            symbols.append(inp[-1])
            i += 1
            xyz = np.array([0, 0, 0])
        if inp[0] == 'atom_frac':
            scaled_positions = True
            if xyz.all():
                fix.append(i)
            elif xyz.any():
                fix_cart.append(FixCartesian(i, xyz))
            floatvect = float(inp[1]), float(inp[2]), float(inp[3])
            positions.append(floatvect)
            symbols.append(inp[-1])
            i += 1
            xyz = np.array([0, 0, 0])

        elif inp[0] == 'lattice_vector':
            floatvect = float(inp[1]), float(inp[2]), float(inp[3])
            cell.append(floatvect)
            n_periodic = n_periodic + 1
            periodic[n_periodic] = True
        elif inp[0] == 'initial_moment':
            magmoms.append(float(inp[1]))
        if inp[0] == 'constrain_relaxation':
            if inp[1] == '.true.':
                fix.append(i)
            elif inp[1] == 'x':
                xyz[0] = 1
            elif inp[1] == 'y':
                xyz[1] = 1
            elif inp[1] == 'z':
                xyz[2] = 1
    if xyz.all():
        fix.append(i)
    elif xyz.any():
        fix_cart.append(FixCartesian(i, xyz))

    if cart_positions and scaled_positions:
        raise Exception("Can't specify atom positions with mixture of "
                        'Cartesian and fractional coordinates')
    elif scaled_positions and periodic.any():
        atoms = Atoms(symbols,
                      scaled_positions=positions,
                      cell=cell,
                      pbc=periodic)
    else:
        atoms = Atoms(symbols, positions)
    if len(magmoms) > 0:
        atoms.set_initial_magnetic_moments(magmoms)
    if periodic.any():
        atoms.set_cell(cell)
        atoms.set_pbc(periodic)
    if len(fix):
        atoms.set_constraint([FixAtoms(indices=fix)] + fix_cart)
    else:
        atoms.set_constraint(fix_cart)
    return atoms
Example #12
0
from vasp import Vasp
from ase.lattice.surface import fcc110
from ase.io import write
from ase.constraints import FixAtoms
atoms = fcc110('Au', size=(2, 1, 6), vacuum=10.0)
constraint = FixAtoms(mask=[atom.tag > 2 for atom in atoms])
atoms.set_constraint(constraint)
write('images/Au-110.png',
      atoms.repeat((2, 2, 1)),
      rotation='-90x',
      show_unit_cell=2)
print Vasp('surfaces/Au-110',
           xc='PBE',
           kpts=[6, 6, 1],
           encut=350,
           ibrion=2,
           isif=2,
           nsw=10,
           atoms=atoms).potential_energy
Example #13
0
from ase.build import fcc100, add_adsorbate
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.optimize import QuasiNewton

# 2x2-Al(001) surface with 3 layers and an
# Au atom adsorbed in a hollow site:
slab = fcc100('Al', size=(2, 2, 3))
add_adsorbate(slab, 'Au', 1.7, 'hollow')
slab.center(axis=2, vacuum=4.0)

# Make sure the structure is correct:
#view(slab)

# Fix second and third layers:
mask = [atom.tag > 1 for atom in slab]
#print(mask)
slab.set_constraint(FixAtoms(mask=mask))

# Use EMT potential:
slab.set_calculator(EMT())

# Initial state:
qn = QuasiNewton(slab, trajectory='initial.traj')
qn.run(fmax=0.05)

# Final state:
slab[-1].x += slab.get_cell()[0, 0] / 2
qn = QuasiNewton(slab, trajectory='final.traj')
qn.run(fmax=0.05)
Example #14
0
import numpy as np

from ase.io import read
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.neb import NEB
from ase.optimize.fire import FIRE as QuasiNewton

initial = read('N2.traj')
final = read('2N.traj')

configs = [initial.copy() for i in range(8)] + [final]

constraint = FixAtoms(mask=[atom.symbol != 'N' for atom in initial])
for config in configs:
    config.set_calculator(EMT())
    config.set_constraint(constraint)

band = NEB(configs)
band.interpolate()

# Create a quickmin object:
relax = QuasiNewton(band)

relax.run(steps=20)

e0 = initial.get_potential_energy()
for config in configs:
    d = config[-2].position - config[-1].position
    print np.linalg.norm(d), config.get_potential_energy() - e0
def test_database_logic(seed, testdir):
    from ase.ga.data import PrepareDB
    from ase.ga.data import DataConnection
    from ase.ga.startgenerator import StartGenerator
    from ase.ga.utilities import closest_distances_generator
    from ase.ga import set_raw_score
    import numpy as np
    from ase.build import fcc111
    from ase.constraints import FixAtoms

    # set up the random number generator
    rng = np.random.RandomState(seed)

    slab = fcc111('Au', size=(4, 4, 2), vacuum=10.0, orthogonal=True)
    slab.set_constraint(FixAtoms(mask=slab.positions[:, 2] <= 10.))

    # define the volume in which the adsorbed cluster is optimized
    # the volume is defined by a corner position (p0)
    # and three spanning vectors (v1, v2, v3)
    pos = slab.get_positions()
    cell = slab.get_cell()
    p0 = np.array([0., 0., max(pos[:, 2]) + 2.])
    v1 = cell[0, :] * 0.8
    v2 = cell[1, :] * 0.8
    v3 = cell[2, :]
    v3[2] = 3.

    # define the closest distance between two atoms of a given species
    blmin = closest_distances_generator(atom_numbers=[47, 79],
                                        ratio_of_covalent_radii=0.7)

    # Define the composition of the atoms to optimize
    atom_numbers = 2 * [47] + 2 * [79]

    # create the starting population
    sg = StartGenerator(slab=slab,
                        blocks=atom_numbers,
                        blmin=blmin,
                        box_to_place_in=[p0, [v1, v2, v3]],
                        rng=rng)

    # generate the starting population
    starting_population = [sg.get_new_candidate() for i in range(20)]

    d = PrepareDB(db_file_name=db_file,
                  simulation_cell=slab,
                  stoichiometry=atom_numbers)

    for a in starting_population:
        d.add_unrelaxed_candidate(a)

    # and now for the actual test
    dc = DataConnection(db_file)

    dc.get_slab()
    dc.get_atom_numbers_to_optimize()

    assert dc.get_number_of_unrelaxed_candidates() == 20

    a1 = dc.get_an_unrelaxed_candidate()
    dc.mark_as_queued(a1)

    assert dc.get_number_of_unrelaxed_candidates() == 19
    assert len(dc.get_all_candidates_in_queue()) == 1

    set_raw_score(a1, 0.0)
    dc.add_relaxed_step(a1)

    assert dc.get_number_of_unrelaxed_candidates() == 19
    assert len(dc.get_all_candidates_in_queue()) == 0

    assert len(dc.get_all_relaxed_candidates()) == 1

    a2 = dc.get_an_unrelaxed_candidate()
    dc.mark_as_queued(a2)
    confid = a2.info['confid']
    assert dc.get_all_candidates_in_queue()[0] == confid

    dc.remove_from_queue(confid)
    assert len(dc.get_all_candidates_in_queue()) == 0
Example #16
0
file_name = file_name_py.replace('.py', '')
file_traj = file_name + '.traj'
start_file = '../In2O3_110_clean.traj'

mode = 'a'
try:
    sys = Trajectory(file_traj, 'r')[-1]
except (IOError, RuntimeError):
    print "Importing trajectory file from: %s" % start_file
    sys = read(start_file)
    sys.center(vacuum=5.0, axis=2)
else:
    print "Importing trajectory file from: %s" % file_traj

set_calc_In2O3(sys)
print "Constraints:"
print "	c1: Fix bottom two layers."
avg_z = np.mean([atom.z for atom in sys])
c1 = FixAtoms(mask=[atom.z < avg_z for atom in sys])
sys.set_constraint(c1)

if testRun == True:
    run_testRun(sys)
else:
    geo_traj = Trajectory(file_traj, mode, sys)
    dyn = LBFGS(sys, trajectory=geo_traj)
    dyn.run(fmax=0.05)
    energy = sys.get_potential_energy()
    print "Energy: %f" % energy
print "Completed %s" % file_name_py
Example #17
0
from ase.build import fcc211, add_adsorbate
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.optimize import QuasiNewton
from ase.neb import NEBTools
from ase.autoneb import AutoNEB

# Pt atom adsorbed in a hollow site:
slab = fcc211('Pt', size=(3, 2, 2), vacuum=4.0)
add_adsorbate(slab, 'Pt', 0.5, (-0.1, 2.7))

# Fix second and third layers:
slab.set_constraint(FixAtoms(range(6, 12)))

# Use EMT potential:
slab.set_calculator(EMT())

# Initial state:
qn = QuasiNewton(slab, trajectory='neb000.traj')
qn.run(fmax=0.05)

# Final state:
slab[-1].x += slab.get_cell()[0, 0]
slab[-1].y += 2.8
qn = QuasiNewton(slab, trajectory='neb001.traj')
qn.run(fmax=0.05)

# Stops PermissionError on Win32 for access to
# the traj file that remains open.
del qn
Example #18
0
def _read_xyz_frame(lines,
                    natoms,
                    properties_parser=key_val_str_to_dict,
                    nvec=0):
    # comment line
    line = next(lines).strip()
    if nvec > 0:
        info = {'comment': line}
    else:
        info = properties_parser(line) if line else {}

    pbc = None
    if 'pbc' in info:
        pbc = info['pbc']
        del info['pbc']
    elif 'Lattice' in info:
        # default pbc for extxyz file containing Lattice
        # is True in all directions
        pbc = [True, True, True]
    elif nvec > 0:
        # cell information given as pseudo-Atoms
        pbc = [False, False, False]

    cell = None
    if 'Lattice' in info:
        # NB: ASE cell is transpose of extended XYZ lattice
        cell = info['Lattice'].T
        del info['Lattice']
    elif nvec > 0:
        # cell information given as pseudo-Atoms
        cell = np.zeros((3, 3))

    if 'Properties' not in info:
        # Default set of properties is atomic symbols and positions only
        info['Properties'] = 'species:S:1:pos:R:3'
    properties, names, dtype, convs = parse_properties(info['Properties'])
    del info['Properties']

    data = []
    for ln in range(natoms):
        try:
            line = next(lines)
        except StopIteration:
            raise XYZError(
                'ase.io.extxyz: Frame has {} atoms, expected {}'.format(
                    len(data), natoms))
        vals = line.split()
        row = tuple([conv(val) for conv, val in zip(convs, vals)])
        data.append(row)

    try:
        data = np.array(data, dtype)
    except TypeError:
        raise XYZError('Badly formatted data '
                       'or end of file reached before end of frame')

    # Read VEC entries if present
    if nvec > 0:
        for ln in range(nvec):
            try:
                line = next(lines)
            except StopIteration:
                raise XYZError(
                    'ase.io.adfxyz: Frame has {} cell vectors, expected {}'.
                    format(len(cell), nvec))
            entry = line.split()

            if not entry[0].startswith('VEC'):
                raise XYZError('Expected cell vector, got {}'.format(entry[0]))
            try:
                n = int(entry[0][3:])
                if n != ln + 1:
                    raise XYZError('Expected VEC{}, got VEC{}'.format(
                        ln + 1, n))
            except:
                raise XYZError('Expected VEC{}, got VEC{}'.format(
                    ln + 1, entry[0][3:]))

            cell[ln] = np.array([float(x) for x in entry[1:]])
            pbc[ln] = True
        if nvec != pbc.count(True):
            raise XYZError('Problem with number of cell vectors')
        pbc = tuple(pbc)

    arrays = {}
    for name in names:
        ase_name, cols = properties[name]
        if cols == 1:
            value = data[name]
        else:
            value = np.vstack([data[name + str(c)] for c in range(cols)]).T
        arrays[ase_name] = value

    symbols = None
    if 'symbols' in arrays:
        symbols = [s.capitalize() for s in arrays['symbols']]
        del arrays['symbols']

    numbers = None
    duplicate_numbers = None
    if 'numbers' in arrays:
        if symbols is None:
            numbers = arrays['numbers']
        else:
            duplicate_numbers = arrays['numbers']
        del arrays['numbers']

    charges = None
    if 'charges' in arrays:
        charges = arrays['charges']
        del arrays['charges']

    positions = None
    if 'positions' in arrays:
        positions = arrays['positions']
        del arrays['positions']

    atoms = Atoms(symbols=symbols,
                  positions=positions,
                  numbers=numbers,
                  charges=charges,
                  cell=cell,
                  pbc=pbc,
                  info=info)

    # Read and set constraints
    if 'move_mask' in arrays:
        if properties['move_mask'][1] == 3:
            atoms.set_constraint([
                FixCartesian(a, mask=arrays['move_mask'][a, :])
                for a in range(natoms)
            ])
        elif properties['move_mask'][1] == 1:
            atoms.set_constraint(FixAtoms(mask=~arrays['move_mask']))
        else:
            raise XYZError('Not implemented constraint')
        del arrays['move_mask']

    for name, array in arrays.items():
        atoms.new_array(name, array)

    if duplicate_numbers is not None:
        atoms.set_atomic_numbers(duplicate_numbers)

    # Load results of previous calculations into SinglePointCalculator
    results = {}
    for key in list(atoms.info.keys()):
        if key in all_properties:
            results[key] = atoms.info[key]
            # special case for stress- convert to Voigt 6-element form
            if key.startswith('stress') and results[key].shape == (3, 3):
                stress = results[key]
                stress = np.array([
                    stress[0, 0], stress[1, 1], stress[2, 2], stress[1, 2],
                    stress[0, 2], stress[0, 1]
                ])
                results[key] = stress
    for key in list(atoms.arrays.keys()):
        if key in all_properties:
            results[key] = atoms.arrays[key]
    if results != {}:
        calculator = SinglePointCalculator(atoms, **results)
        atoms.set_calculator(calculator)
    return atoms
Example #19
0
def read_aims_output(filename, index=-1):
    """Import FHI-aims output files with all data available, i.e.
    relaxations, MD information, force information etc etc etc."""
    from ase import Atoms, Atom
    from ase.calculators.singlepoint import SinglePointCalculator
    from ase.units import Ang, fs
    from ase.constraints import FixAtoms, FixCartesian
    molecular_dynamics = False
    fd = open(filename, 'r')
    cell = []
    images = []
    fix = []
    fix_cart = []
    f = None
    pbc = False
    found_aims_calculator = False
    v_unit = Ang / (1000.0 * fs)
    while True:
        line = fd.readline()
        if not line:
            break
        # if "List of parameters used to initialize the calculator:" in line:
        #     fd.readline()
        #     calc = read_aims_calculator(fd)
        #     calc.out = filename
        #     found_aims_calculator = True
        if "| Number of atoms                   :" in line:
            inp = line.split()
            n_atoms = int(inp[5])
        if "| Unit cell:" in line:
            if not pbc:
                pbc = True
                for i in range(3):
                    inp = fd.readline().split()
                    cell.append([inp[1], inp[2], inp[3]])
        if "Found relaxation constraint for atom" in line:
            xyz = [0, 0, 0]
            ind = int(line.split()[5][:-1]) - 1
            if "All coordinates fixed" in line:
                if ind not in fix:
                    fix.append(ind)
            if "coordinate fixed" in line:
                coord = line.split()[6]
                if coord == 'x':
                    xyz[0] = 1
                elif coord == 'y':
                    xyz[1] = 1
                elif coord == 'z':
                    xyz[2] = 1
                keep = True
                for n, c in enumerate(fix_cart):
                    if ind == c.a:
                        keep = False
                if keep:
                    fix_cart.append(FixCartesian(ind, xyz))
                else:
                    fix_cart[n].mask[xyz.index(1)] = 0
        if "Atomic structure:" in line and not molecular_dynamics:
            fd.readline()
            atoms = Atoms()
            for i in range(n_atoms):
                inp = fd.readline().split()
                atoms.append(Atom(inp[3], (inp[4], inp[5], inp[6])))
        if "Complete information for previous time-step:" in line:
            molecular_dynamics = True
        if "Updated atomic structure:" in line and not molecular_dynamics:
            fd.readline()
            atoms = Atoms()
            velocities = []
            for i in range(n_atoms):
                inp = fd.readline().split()
                if 'lattice_vector' in inp[0]:
                    cell = []
                    for i in range(3):
                        cell += [[float(inp[1]), float(inp[2]), float(inp[3])]]
                        inp = fd.readline().split()
                    atoms.set_cell(cell)
                    inp = fd.readline().split()
                atoms.append(Atom(inp[4], (inp[1], inp[2], inp[3])))
                if molecular_dynamics:
                    inp = fd.readline().split()
        if "Atomic structure (and velocities)" in line:
            fd.readline()
            atoms = Atoms()
            velocities = []
            for i in range(n_atoms):
                inp = fd.readline().split()
                atoms.append(Atom(inp[4], (inp[1], inp[2], inp[3])))
                inp = fd.readline().split()
                velocities += [[
                    float(inp[1]) * v_unit,
                    float(inp[2]) * v_unit,
                    float(inp[3]) * v_unit
                ]]
            atoms.set_velocities(velocities)
            if len(fix):
                atoms.set_constraint([FixAtoms(indices=fix)] + fix_cart)
            else:
                atoms.set_constraint(fix_cart)
            images.append(atoms)
        if "Total atomic forces" in line:
            f = []
            for i in range(n_atoms):
                inp = fd.readline().split()
                f.append([float(inp[2]), float(inp[3]), float(inp[4])])
            if not found_aims_calculator:
                e = images[-1].get_potential_energy()
                images[-1].set_calculator(
                    SinglePointCalculator(atoms, energy=e, forces=f))
            e = None
            f = None
        if "Total energy corrected" in line:
            e = float(line.split()[5])
            if pbc:
                atoms.set_cell(cell)
                atoms.pbc = True
            if not found_aims_calculator:
                atoms.set_calculator(SinglePointCalculator(atoms, energy=e))
            if not molecular_dynamics:
                if len(fix):
                    atoms.set_constraint([FixAtoms(indices=fix)] + fix_cart)
                else:
                    atoms.set_constraint(fix_cart)
                images.append(atoms)
            e = None
            # if found_aims_calculator:
            # calc.set_results(images[-1])
            # images[-1].set_calculator(calc)
    fd.close()
    if molecular_dynamics:
        images = images[1:]

    # return requested images, code borrowed from ase/io/trajectory.py
    if isinstance(index, int):
        return images[index]
    else:
        step = index.step or 1
        if step > 0:
            start = index.start or 0
            if start < 0:
                start += len(images)
            stop = index.stop or len(images)
            if stop < 0:
                stop += len(images)
        else:
            if index.start is None:
                start = len(images) - 1
            else:
                start = index.start
                if start < 0:
                    start += len(images)
            if index.stop is None:
                stop = -1
            else:
                stop = index.stop
                if stop < 0:
                    stop += len(images)
        return [images[i] for i in range(start, stop, step)]
def test_thermochemistry():
    """Tests of the major methods (HarmonicThermo, IdealGasThermo,
    CrystalThermo) from the thermochemistry module."""

    # 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']))
    QuasiNewton(atoms).run(fmax=0.01)
    vib = Vibrations(
        atoms,
        name='harmonicthermo-vib',
        indices=[atom.index for atom in atoms if atom.symbol != 'Cu'])
    vib.run()
    vib.summary()
    vib_energies = vib.get_energies()

    thermo = HarmonicThermo(vib_energies=vib_energies,
                            potentialenergy=atoms.get_potential_energy())
    thermo.get_helmholtz_energy(temperature=298.15)

    # Crystal thermo.
    atoms = bulk('Al', 'fcc', a=4.05)
    calc = EMT()
    atoms.set_calculator(calc)
    energy = atoms.get_potential_energy()

    # Phonon calculator
    N = 7
    ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05)
    ph.run()

    ph.read(acoustic=True)
    phonon_energies, phonon_DOS = ph.dos(kpts=(4, 4, 4), npts=30, delta=5e-4)

    thermo = CrystalThermo(phonon_energies=phonon_energies,
                           phonon_DOS=phonon_DOS,
                           potentialenergy=energy,
                           formula_units=4)
    thermo.get_helmholtz_energy(temperature=298.15)

    # Hindered translator / rotor.
    # (Taken directly from the example given in the documentation.)

    vibs = np.array([
        3049.060670, 3040.796863, 3001.661338, 2997.961647, 2866.153162,
        2750.855460, 1436.792655, 1431.413595, 1415.952186, 1395.726300,
        1358.412432, 1335.922737, 1167.009954, 1142.126116, 1013.918680,
        803.400098, 783.026031, 310.448278, 136.112935, 112.939853, 103.926392,
        77.262869, 60.278004, 25.825447
    ])
    vib_energies = vibs / 8065.54429  # Convert to eV from cm^-1.
    trans_barrier_energy = 0.049313  # eV
    rot_barrier_energy = 0.017675  # eV
    sitedensity = 1.5e15  # cm^-2
    rotationalminima = 6
    symmetrynumber = 1
    mass = 30.07  # amu
    inertia = 73.149  # amu Ang^-2

    thermo = HinderedThermo(vib_energies=vib_energies,
                            trans_barrier_energy=trans_barrier_energy,
                            rot_barrier_energy=rot_barrier_energy,
                            sitedensity=sitedensity,
                            rotationalminima=rotationalminima,
                            symmetrynumber=symmetrynumber,
                            mass=mass,
                            inertia=inertia)

    helmholtz = thermo.get_helmholtz_energy(temperature=298.15)
    target = 1.593  # Taken from documentation example.
    assert (helmholtz - target) < 0.001
Example #21
0
def make_barrier_configurations(pot_path=None, calculator=None,
                                cylinder_r=10, hard_core=False):
    """ Creates the initial and final configurations for the NEB calculation
        The positions in FixedAtoms contrained region are average between
        final and inital configurations

    Parameters
    ----------
    pot_path : sting
        Path to the potential file.
    calculator : type
        Description of parameter `calculator`.
    cylinder_r : float
        Radius of cylinder of unconstrained atoms around the
                    dislocation  in angstrom.
    hard_core : bool
        Type of the core hard or soft.
        If hard is chosen the displacment field is teversed.

    Returns
    -------
    disloc_ini : ase.Atoms
        Initial dislocation configuration.
    disloc_fin : ase.Atoms
        Final dislocation configuration.
    bulk : ase.Atoms
        Perfect bulk configuration for Vitek displacement maps

    """

    if pot_path is not None:
        alat, C11, C12, C44 = get_elastic_constants(pot_path=pot_path)
        # get the cutoff from the potential file
        with open(pot_path) as potfile:
            for i, tmp_str in enumerate(potfile):
                if i == 4:  # read the last number in the fifth line
                    cutoff = float(tmp_str.split()[-1])
                    break

    elif calculator is not None:
        alat, C11, C12, C44 = get_elastic_constants(calculator=calculator)
        cutoff = 5.0  # the value for trainig data for GAP from paper

    cent_x = np.sqrt(6.0)*alat/3.0
    center = (cent_x, 0.0, 0.0)

    disloc_ini, bulk_ini, __ = make_screw_cyl(alat, C11, C12, C44,
                                              cylinder_r=cylinder_r,
                                              cutoff=cutoff,
                                              hard_core=hard_core,
                                              l_extend=center)

    disloc_fin, __, __ = make_screw_cyl(alat, C11, C12, C44,
                                        cylinder_r=cylinder_r,
                                        cutoff=cutoff,
                                        hard_core=hard_core,
                                        center=center)

    # get the fixed atoms constrain
    FixAtoms = disloc_ini.constraints[0]
    # get the indices of fixed atoms
    fixed_atoms_indices = FixAtoms.get_indices()

    # make the average position of fixed atoms
    # between initial and the lastlast position
    ini_fix_pos = disloc_ini.get_positions()[fixed_atoms_indices]
    fin_fix_pos = disloc_fin.get_positions()[fixed_atoms_indices]

    new_av_pos = (ini_fix_pos + fin_fix_pos)/2.0

    positions = disloc_ini.get_positions()
    positions[fixed_atoms_indices] = new_av_pos
    disloc_ini.set_positions(positions, apply_constraint=False)

    positions = disloc_fin.get_positions()
    positions[fixed_atoms_indices] = new_av_pos
    disloc_fin.set_positions(positions, apply_constraint=False)

    return disloc_fin, disloc_ini, bulk_ini
Example #22
0
File: run.py Project: renpj/scan_ts
# Add the Cu2 adsorbate.
adsorbate = Atoms([
    Atom('Cu', atoms[7].position + (0., 0., 2.5)),
    Atom('Cu', atoms[7].position + (0.5, 0.5, 4.5))
])
atoms.extend(adsorbate)
atoms.write('init.cif')
# 输出初始结构 COM
index = [atom.index for atom in atoms if atom.symbol == 'Cu']
masses = atoms.get_masses()[index]
com_init = np.dot(masses, atoms.positions[index]) / masses.sum()

# Constrain the surface to be fixed and a FixAtomsCom or FixAtomsComXY constraint between
# the adsorbate atoms.
constraints = [
    FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == 'Pt']),
    FixAtomsComXY(
        indices=[atom.index for atom in atoms if atom.symbol == 'Cu']),
]
atoms.set_constraint(constraints)
calc = EMT()
atoms.set_calculator(calc)
dyn = BFGS(atoms, trajectory='bfgs.traj')
dyn.run(fmax=0.0001)
atoms.write('final.cif')

# 输出初始结构 COM
com_final = np.dot(masses, atoms.positions[index]) / masses.sum()
print('Center of Mass for initial structure:', com_init)
print('Center of Mass for final structure:', com_final)
Example #23
0
from ase.io import read
from ase.constraints import FixAtoms
from ase.neb import NEB
from JDFTx import JDFTx
from ase.optimize import BFGS
from ase.parallel import rank, size

initial = read('initial.traj')
final = read('final.traj')


constraint = FixAtoms(mask=[atom.tag > 1 for atom in initial])
images = [initial]



for i in range(3):
    image = initial.copy()
    image.set_calculator(JDFTx(executable='mpirun -n 1 -N 1 -c 12 --exclude=node[1001-1032] /home/jfm343/JDFTXDIR/build/jdftx', pseudoDir='/home/jfm343/JDFTXDIR/build/pseudopotentials',pseudoSet='GBRV-pbe',commands={'elec-cutoff' : '20 100','kpoint-folding' : '2 2 1'}))
    image.set_constraint(constraint)
    images.append(image)
images.append(final)

neb = NEB(images, parallel=True)
neb.interpolate()
qn = BFGS(neb, trajectory='neb.traj')
qn.run(fmax=0.05)
Example #24
0
File: db2.py Project: uu1477/MyAse
from ase.test import must_raise


for name in ['y2.json', 'y2.db']:
    c = connect(name)
    print(name, c)

    id = c.reserve(abc=7)
    c.delete([d.id for d in c.select(abc=7)])
    id = c.reserve(abc=7)
    assert c[id].abc == 7
    
    a = c.get_atoms(id)
    c.write(Atoms())
    ch4 = molecule('CH4', calculator=EMT())
    ch4.constraints = [FixAtoms(indices=[1]),
                       FixBondLength(0, 2)]
    f1 = ch4.get_forces()
    print(f1)
    
    c.delete([d.id for d in c.select(C=1)])
    chi = np.array([1 + 0.5j, 0.5])
    id = c.write(ch4, data={'1-butyne': 'bla-bla', 'chi': chi})

    row = c.get(id)
    print(row.data['1-butyne'], row.data.chi)
    assert (row.data.chi == chi).all()
    
    assert len(c.get_atoms(C=1).constraints) == 2

    f2 = c.get(C=1).forces
Example #25
0
                return line.split()[-2]
            else:
                RC = True

    if RC:
        with open(DB_dir + M + '/bulk.out') as f:
            for line in f:
                if 'Lattice constant:' in line:
                    return line.split()[-2]


metal = ['Bi']
metal = sorted(metal)
data = {m: get_a(m) for m in metal}
print(data)

db = connect('A_slab.db')

for k, v in data.items():

    slab = fcc111(k, (2, 2, 3), float(v), 10)
    c = FixAtoms(indices=[a.index for a in slab if a.tag > 1])
    slab.set_constraint(c)

    slab.wrap()
    parameters['spinpol'] = False

    keys['metal'] = k

    db.write(slab, key_value_pairs=keys, data=parameters)
Example #26
0
from gpaw import GPAW, PW

# Initial state:
# 2x2-Al(001) surface with 1 layer and an
# Au atom adsorbed in a hollow site:
slab = fcc100('Al', size=(2, 2, 2))
slab.center(axis=2, vacuum=3.0)
add_adsorbate(slab, 'Au', 1.6, 'hollow')

# Make sure the structure is correct:
view(slab)

# Fix the Al atoms:
mask = [atom.symbol == 'Al' for atom in slab]
print(mask)
fixlayer = FixAtoms(mask=mask)
slab.set_constraint(fixlayer)

# Use GPAW:
calc = GPAW(mode=PW(200), kpts=(2, 2, 1), xc='PBE', txt='hollow.txt')
slab.set_calculator(calc)

qn = QuasiNewton(slab, trajectory='hollow.traj')

# Find optimal height.  The stopping criterion is: the force on the
# Au atom should be less than 0.05 eV/Ang
qn.run(fmax=0.05)

calc.write('hollow.gpw')  # Write gpw output after the minimization

print('energy:', slab.get_potential_energy())
Example #27
0
def read_aims_output(filename, index=-1):
    """Import FHI-aims output files with all data available, i.e.
    relaxations, MD information, force information etc etc etc."""
    from ase import Atoms, Atom
    from ase.calculators.singlepoint import SinglePointCalculator
    from ase.constraints import FixAtoms, FixCartesian

    molecular_dynamics = False
    fd = open(filename, "r")
    cell = []
    images = []
    fix = []
    fix_cart = []
    f = None
    pbc = False
    found_aims_calculator = False
    stress = None
    for line in fd:
        # if "List of parameters used to initialize the calculator:" in line:
        #     next(fd)
        #     calc = read_aims_calculator(fd)
        #     calc.out = filename
        #     found_aims_calculator = True
        if "| Number of atoms                   :" in line:
            inp = line.split()
            n_atoms = int(inp[5])
        if "| Unit cell:" in line:
            if not pbc:
                pbc = True
                for i in range(3):
                    inp = next(fd).split()
                    cell.append([inp[1], inp[2], inp[3]])
        if "Found relaxation constraint for atom" in line:
            xyz = [0, 0, 0]
            ind = int(line.split()[5][:-1]) - 1
            if "All coordinates fixed" in line:
                if ind not in fix:
                    fix.append(ind)
            if "coordinate fixed" in line:
                coord = line.split()[6]
                if coord == "x":
                    xyz[0] = 1
                elif coord == "y":
                    xyz[1] = 1
                elif coord == "z":
                    xyz[2] = 1
                keep = True
                for n, c in enumerate(fix_cart):
                    if ind == c.a:
                        keep = False
                if keep:
                    fix_cart.append(FixCartesian(ind, xyz))
                else:
                    fix_cart[n].mask[xyz.index(1)] = 0

        if "Atomic structure:" in line and not molecular_dynamics:
            next(fd)
            atoms = Atoms()
            for _ in range(n_atoms):
                inp = next(fd).split()
                atoms.append(Atom(inp[3], (inp[4], inp[5], inp[6])))

        if "Complete information for previous time-step:" in line:
            molecular_dynamics = True

        if "Updated atomic structure:" in line and not molecular_dynamics:
            atoms = _parse_atoms(fd, n_atoms=n_atoms)
        elif "Atomic structure (and velocities)" in line:
            next(fd)
            atoms = Atoms()
            velocities = []
            for i in range(n_atoms):
                inp = next(fd).split()
                atoms.append(Atom(inp[4], (inp[1], inp[2], inp[3])))
                inp = next(fd).split()
                floatvect = [v_unit * float(l) for l in inp[1:4]]
                velocities.append(floatvect)
            atoms.set_velocities(velocities)
            if len(fix):
                atoms.set_constraint([FixAtoms(indices=fix)] + fix_cart)
            else:
                atoms.set_constraint(fix_cart)
            images.append(atoms)

        # if we enter here, the SocketIO/PIMD Wrapper was used
        elif ("Atomic structure that "
              "was used in the preceding time step of the wrapper") in line:
            # parse atoms and add calculator information, i.e., the energies
            # and forces that were already collected
            atoms = _parse_atoms(fd, n_atoms=n_atoms)
            results = images[-1].calc.results
            atoms.calc = SinglePointCalculator(atoms, **results)

            # replace last image with updated atoms
            images[-1] = atoms

            # make sure `atoms` does not point to `images[-1` later on
            atoms = atoms.copy()

        # FlK: add analytical stress and replace stress=None
        if "Analytical stress tensor - Symmetrized" in line:
            # scroll to significant lines
            for _ in range(4):
                next(fd)
            stress = []
            for _ in range(3):
                inp = next(fd)
                stress.append([float(i) for i in inp.split()[2:5]])

        if "Total atomic forces" in line:
            f = []
            for i in range(n_atoms):
                inp = next(fd).split()
                # FlK: use inp[-3:] instead of inp[1:4] to make sure this works
                # when atom number is not preceded by a space.
                f.append([float(i) for i in inp[-3:]])
            if not found_aims_calculator:
                e = images[-1].get_potential_energy()
                # FlK: Add the stress if it has been computed
                if stress is None:
                    calc = SinglePointCalculator(atoms, energy=e, forces=f)
                else:
                    calc = SinglePointCalculator(atoms,
                                                 energy=e,
                                                 forces=f,
                                                 stress=stress)
                images[-1].calc = calc
            e = None
            f = None

        if "Total energy corrected" in line:
            e = float(line.split()[5])
            if pbc:
                atoms.set_cell(cell)
                atoms.pbc = True
            if not found_aims_calculator:
                atoms.calc = SinglePointCalculator(atoms, energy=e)
            if not molecular_dynamics:
                if len(fix):
                    atoms.set_constraint([FixAtoms(indices=fix)] + fix_cart)
                else:
                    atoms.set_constraint(fix_cart)
                images.append(atoms)
            e = None
            # if found_aims_calculator:
            # calc.set_results(images[-1])
            # images[-1].calc = calc

        # FlK: add stress per atom
        if "Per atom stress (eV) used for heat flux calculation" in line:
            # scroll to boundary
            next(l for l in fd if "-------------" in l)

            stresses = []
            for l in [next(fd) for _ in range(n_atoms)]:
                # Read stresses
                xx, yy, zz, xy, xz, yz = [float(d) for d in l.split()[2:8]]
                stresses.append([[xx, xy, xz], [xy, yy, yz], [xz, yz, zz]])

            if not found_aims_calculator:
                e = images[-1].get_potential_energy()
                f = images[-1].get_forces()
                stress = images[-1].get_stress(voigt=False)

                calc = SinglePointCalculator(atoms,
                                             energy=e,
                                             forces=f,
                                             stress=stress,
                                             stresses=stresses)
                images[-1].calc = calc

    fd.close()
    if molecular_dynamics:
        images = images[1:]

    # return requested images, code borrowed from ase/io/trajectory.py
    if isinstance(index, int):
        return images[index]
    else:
        step = index.step or 1
        if step > 0:
            start = index.start or 0
            if start < 0:
                start += len(images)
            stop = index.stop or len(images)
            if stop < 0:
                stop += len(images)
        else:
            if index.start is None:
                start = len(images) - 1
            else:
                start = index.start
                if start < 0:
                    start += len(images)
            if index.stop is None:
                stop = -1
            else:
                stop = index.stop
                if stop < 0:
                    stop += len(images)
        return [images[i] for i in range(start, stop, step)]
Example #28
0
# Benzene on the slab
from jasp import *
from ase.lattice.surface import fcc111, add_adsorbate
from ase.structure import molecule
from ase.constraints import FixAtoms
atoms = fcc111('Au', size=(3,3,3), vacuum=10)
benzene = molecule('C6H6')
benzene.translate(-benzene.get_center_of_mass())
# I want the benzene centered on the position in the middle of atoms
# 20, 22, 23 and 25
p = (atoms.positions[20] +
     atoms.positions[22] +
     atoms.positions[23] +
     atoms.positions[25])/4.0 + [0.0, 0.0, 3.05]
benzene.translate(p)
atoms += benzene
# now we constrain the slab
c = FixAtoms(mask=[atom.symbol=='Au' for atom in atoms])
atoms.set_constraint(c)
#from ase.visualize import view; view(atoms)
with jasp('surfaces/Au-benzene-pbe',
          xc='PBE',
          encut=350,
          kpts=(4,4,1),
          ibrion=1,
          nsw=100,
          atoms=atoms) as calc:
    print atoms.get_potential_energy()
Example #29
0
def read_aims(filename, apply_constraints=True):
    """Import FHI-aims geometry type files.

    Reads unitcell, atom positions and constraints from
    a geometry.in file.

    If geometric constraint (symmetry parameters) are in the file
    include that information in atoms.info["symmetry_block"]
    """

    from ase import Atoms
    from ase.constraints import (
        FixAtoms,
        FixCartesian,
        FixScaledParametricRelations,
        FixCartesianParametricRelations,
    )
    import numpy as np

    atoms = Atoms()
    with open(filename, "r") as fd:
        lines = fd.readlines()

    positions = []
    cell = []
    symbols = []
    velocities = []
    magmoms = []
    symmetry_block = []
    charges = []
    fix = []
    fix_cart = []
    xyz = np.array([0, 0, 0])
    i = -1
    n_periodic = -1
    periodic = np.array([False, False, False])
    cart_positions, scaled_positions = False, False
    for line in lines:
        inp = line.split()
        if inp == []:
            continue
        if inp[0] == "atom":
            cart_positions = True
            if xyz.all():
                fix.append(i)
            elif xyz.any():
                fix_cart.append(FixCartesian(i, xyz))
            floatvect = float(inp[1]), float(inp[2]), float(inp[3])
            positions.append(floatvect)
            magmoms.append(0.0)
            charges.append(0.0)
            symbols.append(inp[-1])
            i += 1
            xyz = np.array([0, 0, 0])
        elif inp[0] == "atom_frac":
            scaled_positions = True
            if xyz.all():
                fix.append(i)
            elif xyz.any():
                fix_cart.append(FixCartesian(i, xyz))
            floatvect = float(inp[1]), float(inp[2]), float(inp[3])
            positions.append(floatvect)
            magmoms.append(0.0)
            symbols.append(inp[-1])
            i += 1
            xyz = np.array([0, 0, 0])

        elif inp[0] == "lattice_vector":
            floatvect = float(inp[1]), float(inp[2]), float(inp[3])
            cell.append(floatvect)
            n_periodic = n_periodic + 1
            periodic[n_periodic] = True

        elif inp[0] == "initial_moment":
            magmoms[-1] = float(inp[1])

        elif inp[0] == "initial_charge":
            charges[-1] = float(inp[1])

        elif inp[0] == "constrain_relaxation":
            if inp[1] == ".true.":
                fix.append(i)
            elif inp[1] == "x":
                xyz[0] = 1
            elif inp[1] == "y":
                xyz[1] = 1
            elif inp[1] == "z":
                xyz[2] = 1

        elif inp[0] == "velocity":
            floatvect = [v_unit * float(l) for l in inp[1:4]]
            velocities.append(floatvect)

        elif inp[0] in [
                "symmetry_n_params",
                "symmetry_params",
                "symmetry_lv",
                "symmetry_frac",
        ]:
            symmetry_block.append(" ".join(inp))

    if xyz.all():
        fix.append(i)
    elif xyz.any():
        fix_cart.append(FixCartesian(i, xyz))

    if cart_positions and scaled_positions:
        raise Exception("Can't specify atom positions with mixture of "
                        "Cartesian and fractional coordinates")
    elif scaled_positions and periodic.any():
        atoms = Atoms(symbols,
                      scaled_positions=positions,
                      cell=cell,
                      pbc=periodic)
    else:
        atoms = Atoms(symbols, positions)

    if len(velocities) > 0:
        if len(velocities) != len(positions):
            raise Exception(
                "Number of positions and velocities have to coincide.")
        atoms.set_velocities(velocities)

    fix_params = []

    if len(symmetry_block) > 5:
        params = symmetry_block[1].split()[1:]

        lattice_expressions = []
        lattice_params = []

        atomic_expressions = []
        atomic_params = []

        n_lat_param = int(symmetry_block[0].split(" ")[2])

        lattice_params = params[:n_lat_param]
        atomic_params = params[n_lat_param:]

        for ll, line in enumerate(symmetry_block[2:]):
            expression = " ".join(line.split(" ")[1:])
            if ll < 3:
                lattice_expressions += expression.split(",")
            else:
                atomic_expressions += expression.split(",")

        fix_params.append(
            FixCartesianParametricRelations.from_expressions(
                list(range(3)),
                lattice_params,
                lattice_expressions,
                use_cell=True,
            ))

        fix_params.append(
            FixScaledParametricRelations.from_expressions(
                list(range(len(atoms))), atomic_params, atomic_expressions))

    if any(magmoms):
        atoms.set_initial_magnetic_moments(magmoms)
    if any(charges):
        atoms.set_initial_charges(charges)

    if periodic.any():
        atoms.set_cell(cell)
        atoms.set_pbc(periodic)
    if len(fix):
        atoms.set_constraint([FixAtoms(indices=fix)] + fix_cart + fix_params)
    else:
        atoms.set_constraint(fix_cart + fix_params)

    if fix_params and apply_constraints:
        atoms.set_positions(atoms.get_positions())
    return atoms
Example #30
0
b = a / sqrt(2)
h = b / 2
initial = Atoms('Al2',
                positions=[(0, 0, 0), (a / 2, b / 2, -h)],
                cell=(a, b, 2 * h),
                pbc=(1, 1, 0))
initial *= (2, 2, 2)
initial.append(Atom('Al', (a / 2, b / 2, 3 * h)))
initial.center(vacuum=4.0, axis=2)

N = len(initial)  # number of atoms

# Make a mask of zeros and ones that select fixed atoms - the two
# bottom layers:
mask = initial.positions[:, 2] - min(initial.positions[:, 2]) < 1.5 * h
constraint = FixAtoms(mask=mask)
initial.set_constraint(constraint)

# Calculate using EMT:
initial.calc = EMT()

# Relax the initial state:
QuasiNewton(initial).run(fmax=0.05)
e0 = initial.get_potential_energy()

traj = Trajectory('dimer_along.traj', 'w', initial)
traj.write()

# Making dimer mask list:
d_mask = [False] * (N - 1) + [True]
Example #31
0
    def get_atoms(structure, **kwargs):
        """
        Returns ASE Atoms object from pymatgen structure or molecule.

        Args:
            structure: pymatgen.core.structure.Structure or pymatgen.core.structure.Molecule
            **kwargs: other keyword args to pass into the ASE Atoms constructor

        Returns:
            ASE Atoms object
        """
        if not structure.is_ordered:
            raise ValueError("ASE Atoms only supports ordered structures")
        if not ase_loaded:
            raise ImportError(
                "AseAtomsAdaptor requires the ASE package.\nUse `pip install ase` or `conda install ase -c conda-forge`"
            )

        # Construct the base ASE Atoms object
        symbols = [str(site.specie.symbol) for site in structure]
        positions = [site.coords for site in structure]
        if hasattr(structure, "lattice"):
            cell = structure.lattice.matrix
            pbc = True
        else:
            cell = None
            pbc = None

        atoms = Atoms(symbols=symbols,
                      positions=positions,
                      pbc=pbc,
                      cell=cell,
                      **kwargs)

        # Set the site magmoms in the ASE Atoms object
        # Note: ASE distinguishes between initial and converged
        # magnetic moment site properties, whereas pymatgen does not. Therefore, we
        # have to distinguish between these two when constructing the Structure/Molecule.
        # The mapping selected here is:
        # ASE initial magmom <--> Pymatgen "magmom"
        # ASE final magmom <--> Pymatgen "final_magmom"
        # ASE initial charge <--> Pymatgen "charge"
        # ASE final charge <--> Pymatgen "final_charge"
        if "magmom" in structure.site_properties:
            initial_magmoms = structure.site_properties["magmom"]
            atoms.set_initial_magnetic_moments(initial_magmoms)
        if "charge" in structure.site_properties:
            initial_charges = structure.site_properties["charge"]
            atoms.set_initial_charges(initial_charges)

        if "final_magmom" in structure.site_properties:
            magmoms = structure.site_properties["final_magmom"]
        else:
            magmoms = None
        if "final_charge" in structure.site_properties:
            charges = structure.site_properties["final_charge"]
        else:
            charges = None
        if magmoms or charges:
            if magmoms and charges:
                calc = SinglePointDFTCalculator(
                    atoms, **{
                        "magmoms": magmoms,
                        "charges": charges
                    })
            elif magmoms:
                calc = SinglePointDFTCalculator(atoms, **{"magmoms": magmoms})
            elif charges:
                calc = SinglePointDFTCalculator(atoms, **{"charges": charges})
            atoms.calc = calc

        # Get the oxidation states from the structure
        oxi_states = [
            getattr(site.specie, "oxi_state", None) for site in structure
        ]

        # Read in selective dynamics if present. Note that the ASE FixAtoms class fixes (x,y,z), so
        # here we make sure that [False, False, False] or [True, True, True] is set for the site selective
        # dynamics property. As a consequence, if only a subset of dimensions are fixed, this won't get passed to ASE.
        if "selective_dynamics" in structure.site_properties:
            fix_atoms = []
            for site in structure:
                site_prop = site.properties["selective_dynamics"]
                if site_prop not in [[True, True, True], [False, False,
                                                          False]]:
                    raise ValueError(
                        "ASE FixAtoms constraint does not support selective dynamics in only some dimensions."
                        "Remove the selective dynamics and try again if you do not need them."
                    )
                is_fixed = bool(~np.all(site.properties["selective_dynamics"]))
                fix_atoms.append(is_fixed)

        else:
            fix_atoms = None

        # Set the selective dynamics with the FixAtoms class.
        if fix_atoms is not None:
            atoms.set_constraint(FixAtoms(mask=fix_atoms))

        # Add any remaining site properties to the ASE Atoms object
        for prop in structure.site_properties:
            if prop not in [
                    "magmom", "charge", "final_magmom", "final_charge",
                    "selective_dynamics"
            ]:
                atoms.set_array(prop,
                                np.array(structure.site_properties[prop]))
        if np.any(oxi_states):
            atoms.set_array("oxi_states", np.array(oxi_states))

        return atoms