Пример #1
0
def fcc211(symbol, size, a=None, vacuum=None, orthogonal=True):
    """FCC(211) surface.

    Does not currently support special adsorption sites.

    Currently only implemented for *orthogonal=True* with size specified
    as (i, j, k), where i, j, and k are number of atoms in each direction.
    i must be divisible by 3 to accommodate the step width.
    """
    if not orthogonal:
        raise NotImplementedError('Only implemented for orthogonal '
                                  'unit cells.')
    if size[0] % 3 != 0:
        raise NotImplementedError('First dimension of size must be '
                                  'divisible by 3.')
    atoms = FaceCenteredCubic(symbol,
                              directions=[[1, -1, -1],
                                          [0, 2, -2],
                                          [2, 1, 1]],
                              miller=(None, None, (2, 1, 1)),
                              latticeconstant=a,
                              size=(1, 1, 1),
                              pbc=True)
    z = (size[2] + 1) // 2
    atoms = atoms.repeat((size[0] // 3, size[1], z))
    if size[2] % 2:  # Odd: remove bottom layer and shrink cell.
        remove_list = [atom.index for atom in atoms
                       if atom.z < atoms[1].z]
        del atoms[remove_list]
        dz = atoms[0].z
        atoms.translate((0., 0., -dz))
        atoms.cell[2][2] -= dz

    atoms.cell[2] = 0.0
    atoms.pbc[2] = False
    if vacuum:
        atoms.center(vacuum, axis=2)

    # Renumber systematically from top down.
    orders = [(atom.index, round(atom.x, 3), round(atom.y, 3),
               -round(atom.z, 3), atom.index) for atom in atoms]
    orders.sort(key=itemgetter(3, 1, 2))
    newatoms = atoms.copy()
    for index, order in enumerate(orders):
        newatoms[index].position = atoms[order[0]].position.copy()

    # Add empty 'sites' dictionary for consistency with other functions
    newatoms.info['adsorbate_info'] = {'sites': {}}
    return newatoms
Пример #2
0
def fcc211(symbol, size, a=None, vacuum=None, orthogonal=True):
    """FCC(211) surface.

    Does not currently support special adsorption sites.

    Currently only implemented for *orthogonal=True* with size specified
    as (i, j, k), where i, j, and k are number of atoms in each direction.
    i must be divisible by 3 to accommodate the step width.
    """
    if not orthogonal:
        raise NotImplementedError('Only implemented for orthogonal '
                                  'unit cells.')
    if size[0] % 3 != 0:
        raise NotImplementedError('First dimension of size must be '
                                  'divisible by 3.')
    atoms = FaceCenteredCubic(symbol,
                              directions=[[1, -1, -1],
                                          [0, 2, -2],
                                          [2, 1, 1]],
                              miller=(None, None, (2, 1, 1)),
                              latticeconstant=a,
                              size=(1, 1, 1),
                              pbc=True)
    z = (size[2] + 1) // 2
    atoms = atoms.repeat((size[0] // 3, size[1], z))
    if size[2] % 2:  # Odd: remove bottom layer and shrink cell.
        remove_list = [atom.index for atom in atoms
                       if atom.z < atoms[1].z]
        del atoms[remove_list]
        dz = atoms[0].z
        atoms.translate((0., 0., -dz))
        atoms.cell[2][2] -= dz

    atoms.cell[2] = 0.0
    atoms.pbc[1] = False
    if vacuum:
        atoms.center(vacuum, axis=2)

    # Renumber systematically from top down.
    orders = [(atom.index, round(atom.x, 3), round(atom.y, 3),
               -round(atom.z, 3), atom.index) for atom in atoms]
    orders.sort(key=itemgetter(3, 1, 2))
    newatoms = atoms.copy()
    for index, order in enumerate(orders):
        newatoms[index].position = atoms[order[0]].position.copy()
    return newatoms
Пример #3
0
def test_center():
    # flake8: noqa
    "Test that atoms.center() works when adding vacuum ()"

    import numpy as np
    from math import pi, sqrt, cos
    from ase import data
    from ase.lattice.cubic import FaceCenteredCubic

    def checkang(a, b, phi):
        "Check the angle between two vectors."
        cosphi = np.dot(a, b) / sqrt(np.dot(a, a) * np.dot(b, b))
        assert np.abs(cosphi - cos(phi)) < 1e-10

    symb = "Cu"
    Z = data.atomic_numbers[symb]
    a0 = data.reference_states[Z]['a']

    # (100) oriented block
    atoms = FaceCenteredCubic(size=(5, 5, 5), symbol="Cu", pbc=(1, 1, 0))
    assert len(atoms) == 5 * 5 * 5 * 4
    c = atoms.get_cell()
    checkang(c[0], c[1], pi / 2)
    checkang(c[0], c[2], pi / 2)
    checkang(c[1], c[2], pi / 2)
    assert np.abs(5 * a0 - c[2, 2]) < 1e-10

    # Add vacuum in one direction
    vac = 10.0
    atoms.center(axis=2, vacuum=vac)
    c = atoms.get_cell()
    checkang(c[0], c[1], pi / 2)
    checkang(c[0], c[2], pi / 2)
    checkang(c[1], c[2], pi / 2)
    assert np.abs(4.5 * a0 + 2 * vac - c[2, 2]) < 1e-10

    # Add vacuum in all directions
    vac = 4.0
    atoms.center(vacuum=vac)
    c = atoms.get_cell()
    checkang(c[0], c[1], pi / 2)
    checkang(c[0], c[2], pi / 2)
    checkang(c[1], c[2], pi / 2)
    assert np.abs(4.5 * a0 + 2 * vac - c[0, 0]) < 1e-10
    assert np.abs(4.5 * a0 + 2 * vac - c[1, 1]) < 1e-10
    assert np.abs(4.5 * a0 + 2 * vac - c[2, 2]) < 1e-10

    # Now a general unit cell
    atoms = FaceCenteredCubic(size=(5, 5, 5),
                              directions=[[1, 0, 0], [0, 1, 0], [1, 0, 1]],
                              symbol="Cu",
                              pbc=(1, 1, 0))
    assert len(atoms) == 5 * 5 * 5 * 2
    c = atoms.get_cell()
    checkang(c[0], c[1], pi / 2)
    checkang(c[0], c[2], pi / 4)
    checkang(c[1], c[2], pi / 2)
    assert np.abs(2.5 * a0 - c[2, 2]) < 1e-10

    # Add vacuum in one direction
    vac = 10.0
    atoms.center(axis=2, vacuum=vac)
    c = atoms.get_cell()
    checkang(c[0], c[1], pi / 2)
    checkang(c[0], c[2], pi / 4)
    checkang(c[1], c[2], pi / 2)
    assert np.abs(2 * a0 + 2 * vac - c[2, 2]) < 1e-10

    # Recenter without specifying vacuum
    atoms.center()
    c = atoms.get_cell()
    checkang(c[0], c[1], pi / 2)
    checkang(c[0], c[2], pi / 4)
    checkang(c[1], c[2], pi / 2)
    assert np.abs(2 * a0 + 2 * vac - c[2, 2]) < 1e-10

    a2 = atoms.copy()

    # Add vacuum in all directions
    vac = 4.0
    atoms.center(vacuum=vac)
    c = atoms.get_cell()
    checkang(c[0], c[1], pi / 2)
    checkang(c[0], c[2], pi / 4)
    checkang(c[1], c[2], pi / 2)
    assert np.abs(4.5 * a0 + 2 * vac - c[1, 1]) < 1e-10
    assert np.abs(2 * a0 + 2 * vac - c[2, 2]) < 1e-10

    # One axis at the time:
    for i in range(3):
        a2.center(vacuum=vac, axis=i)

    assert abs(atoms.positions - a2.positions).max() < 1e-12
    assert abs(atoms.cell - a2.cell).max() < 1e-12
Пример #4
0
    def get_structure(self, name, elements, a=None, c=None, l=None):
        # Check number of elements
        if name[:3] in ['fcc', 'hcp']:
            if len(elements) != 1:
                raise ValueError("Tuple of elements must be of length one")
        if name[:3] in ['l12', 'l10'] or name[:2] == 'B2':
            if len(elements) != 2:
                raise ValueError("Tuple of elements must be of length two")

        # Get lattice constants
        if a is None:
            if name[:2] == 'B2':
                a = self.get_lattice_constant_a(name[:2], elements)
            elif name[:3] in ['fcc', 'hcp', 'bcc', 'l12', 'l10']:
                a = self.get_lattice_constant_a(name[:3], elements)

        if c is None:
            if name[:3] in ['hcp', 'l10']:
                c = self.get_lattice_constant_c(name[:3], elements)

        # Get size
        if name in ['fcc', 'hcp', 'bcc', 'l12', 'l10', 'B2']:
            size = self.properties[name + '_size']
        elif name in ['fcc100', 'fcc111', 'hcp0001']:
            size = self.properties[name + '_size'][:2] + (l, )

        # Make structure
        if name == 'fcc':
            atoms = FaceCenteredCubic(symbol=elements[0],
                                      size=size,
                                      latticeconstant=a)
        elif name == 'hcp':
            atoms = HexagonalClosedPacked(symbol=elements[0],
                                          size=size,
                                          directions=[[2, -1, -1, 0],
                                                      [0, 1, -1, 0],
                                                      [0, 0, 0, 1]],
                                          latticeconstant=(a, c))
        elif name == 'bcc':
            atoms = BodyCenteredCubic(symbol=elements[0],
                                      size=size,
                                      latticeconstant=a)
        elif name == 'B2':
            atoms = B2(symbol=elements, size=size, latticeconstant=a)
        elif name == 'l12':
            atoms = L1_2(symbol=elements, size=size, latticeconstant=a)
        elif name == 'l10':
            atoms = L1_0(symbol=elements, size=size, latticeconstant=(a, c))
        elif name == 'fcc100':
            atoms = fcc100(symbol=elements[0], size=size, a=a, vacuum=10.0)
        elif name == 'fcc111':
            atoms = fcc111(symbol=elements[0],
                           size=size,
                           a=a,
                           vacuum=10.0,
                           orthogonal=True)
        elif name == 'hcp0001':
            atoms = hcp0001(symbol=elements[0],
                            size=size,
                            a=a,
                            c=c,
                            vacuum=10.0,
                            orthogonal=True)
        elif name == 'hcp1010A':
            raise ValueError("Structure '%s' not supported" % (name, ))
            atoms = None
        elif name == 'hcp1010B':
            raise ValueError("Structure '%s' not supported" % (name, ))
            atoms = None
        elif name == 'l12100':
            n = (l + 1) / 2
            atoms = L1_2(symbol=elements, size=(8, 8, n), latticeconstant=a)
            atoms.set_pbc([True, True, False])
            # Remove layers
            atoms = atoms[atoms.get_positions()[:, 2] > 0.1 * a]
            # Set vacuum
            atoms.center(axis=2, vacuum=10.0)
        elif name == 'l12111':
            if l % 3 == 0:
                n = l / 3
                c = 0
            else:
                n = l / 3 + 1
                c = 3 - l % 3
            atoms = L1_2(
                symbol=elements,
                size=(8, 4, n),
                #directions=[[1,-1,0],[1,0,-1],[1,1,1]], latticeconstant=a)
                directions=[[1, -1, 0], [1, 1, -2], [1, 1, 1]],
                latticeconstant=a)
            atoms.set_pbc([True, True, False])
            # Wrap positions
            scpos = atoms.get_scaled_positions()
            scpos[scpos > (1.0 - 1e-12)] = 0.0
            atoms.set_scaled_positions(scpos)
            # Remove layers
            if c > 0:
                atoms = atoms[atoms.get_positions()[:, 2] > (c - 0.5) * a /
                              np.sqrt(3.0)]
            # Set vacuum
            atoms.center(axis=2, vacuum=10.0)
        else:
            raise ValueError("Structure '%s' not supported" % (name, ))
        return atoms
Пример #5
0
if rank == 0:
    print("#"*60)
    print("GPAW benchmark: Copper Sheet")
    print("  dimensions: x=%d, y=%d, z=%d" % (x, y, z))
    print("  grid spacing: h=%f" % h)
    print("  Brillouin-zone sampling: kpts=" + str(kpts))
    print("  MPI task: %d out of %d" % (rank, size))
    print("  using MICs: " + str(use_mic))
    print("#"*60)
    print("")

# setup the system
atoms = FaceCenteredCubic(directions=[[1,-1,0], [1,1,-2], [1,1,1]],
        size=(x,y,z), symbol='Cu', pbc=(1,1,0))
#add_vacuum(atoms, 10.0)
atoms.center(vacuum=6.0, axis=2)
calc = GPAW(h=h, nbands=-20, width=0.2,
            kpts=kpts, xc='PBE',
            maxiter=maxiter,
            txt=txt, eigensolver=RMM_DIIS(niter=2),
            parallel={'sl_auto': True},
            mixer=Mixer(0.1, 5, 100),
           )
atoms.set_calculator(calc)

# execute the run
try:
    atoms.get_potential_energy()
except ConvergenceError:
    pass
Пример #6
0
symb = "Cu"
Z = data.atomic_numbers[symb]
a0 = data.reference_states[Z]['a']

# (100) oriented block
atoms = FaceCenteredCubic(size=(5,5,5), symbol="Cu", pbc=(1,1,0))
assert len(atoms) == 5*5*5*4
c = atoms.get_cell()
checkang(c[0], c[1], pi/2)
checkang(c[0], c[2], pi/2)
checkang(c[1], c[2], pi/2)
assert np.abs(5 * a0 - c[2,2]) < 1e-10

# Add vacuum in one direction
vac = 10.0
atoms.center(axis=2, vacuum=vac)
c = atoms.get_cell()
checkang(c[0], c[1], pi/2)
checkang(c[0], c[2], pi/2)
checkang(c[1], c[2], pi/2)
assert np.abs(4.5 * a0 + 2* vac - c[2,2]) < 1e-10

# Add vacuum in all directions
vac = 4.0
atoms.center(vacuum=vac)
c = atoms.get_cell()
checkang(c[0], c[1], pi/2)
checkang(c[0], c[2], pi/2)
checkang(c[1], c[2], pi/2)
assert np.abs(4.5 * a0 + 2* vac - c[0,0]) < 1e-10
assert np.abs(4.5 * a0 + 2* vac - c[1,1]) < 1e-10
Пример #7
0
from ase.io import write, read
from ase import units
from ase.lattice.cubic import FaceCenteredCubic
from ase.md.verlet import VelocityVerlet
from ase.optimize import FIRE
from ase.md.langevin import Langevin


# Parameters for the Morse potential for Cu
D = 0.3429
r0 = 2.866
alpha = 1.3588


atoms = FaceCenteredCubic(latticeconstant=1.5, symbol='Cu', pbc=False, size=(3,3,3))
atoms.center(vacuum=100)

atoms.set_calculator(MorsePotential(D=D, alpha=alpha, r0=r0))

dyn = FIRE(atoms, trajectory='relax.traj')

dyn.run(fmax=0.01)

write('relax.xyz', read('relax.traj@:')) # uncomment this line for Task 2


open('langevin.log', 'w').close() # clean current log file
# dyn = VelocityVerlet(atoms, dt=1 * units.fs,
#                      trajectory='md.traj', logfile='md.log')

# dyn.run(1000)
Пример #8
0
from gpaw.mpi import size, rank
from gpaw import GPAW, Mixer, ConvergenceError
from gpaw.occupations import FermiDirac
from gpaw.eigensolvers.rmmdiis import RMMDIIS
from gpaw.test import equal

# no. of replicates in each dimension (increase to scale up the system)
x = 2
y = 2
z = 4
# setup the system
atoms = FaceCenteredCubic(directions=[[1, -1, 0], [1, 1, -2], [1, 1, 1]],
                          size=(x, y, z),
                          symbol='Cu',
                          pbc=(0, 0, 1))
atoms.center(vacuum=6.0, axis=0)
atoms.center(vacuum=6.0, axis=1)

# Simulation parameters
h = 0.22
kpts = (1, 1, 8)
txt = 'output_M_%i.txt' % size
maxiter = 15

# output benchmark parameters
if rank == 0:
    print("#" * 60)
    print("GPAW benchmark: Copper Filament")
    print("  dimensions: x=%d, y=%d, z=%d" % (x, y, z))
    print("  grid spacing: h=%f" % h)
    print("  Brillouin-zone sampling: kpts=" + str(kpts))
radius = 15
size = [14, 10, 100]

# radius = 30
# size = [28, 20, 100]  # 51500 atoms

a = FaceCenteredCubic('Au',
                      directions=[[1, 0, -1], [0, 1, 0], [1, 0, 1]],
                      size=size)
c = a.cell.diagonal() / 2

dir1 = [sqrt(2), 1, 0]
dir2 = [sqrt(2), -1, 0]
dir3 = [0, 1, 0]

dir1 = np.array(dir1) / np.linalg.norm(dir1)
dir2 = np.array(dir2) / np.linalg.norm(dir2)
dir3 = np.array(dir3) / np.linalg.norm(dir3)

r = a.get_positions() - c
m = np.abs(r.dot(dir1)) > radius
m = np.logical_or(m, np.abs(r.dot(dir2)) > radius)
m = np.logical_or(m, np.abs(r.dot(dir3)) > radius)
del a[m]

a.center()
a.set_pbc([False, False, True])

io.write('whisker.xyz', a)
io.write('whisker.data', a, format='lammps-data')
Пример #10
0
fast = False

#AsapThreads()

cpulayout = (1, 1, 2)

element = 'Pt'
size = (20, 20, 100)

master = world.rank == 0

if master:
    atoms = FaceCenteredCubic(symbol=element,
                              size=size,
                              pbc=(True, True, False))
    atoms.center(vacuum=10.0, axis=2)
    atoms.set_momenta(np.zeros((len(atoms), 3)))
    # Select an atom to get a kick
    r = atoms.get_positions()
    uc = atoms.get_cell()
    x = r[:, 0] - 0.5 * uc[0, 0]
    y = r[:, 1] - 0.5 * uc[1, 1]
    z = r[:, 2]
    zprime = z - 0.01 * (x * x + y * y)
    n = np.argmax(zprime)
    #a = atoms[n]
    #dp = np.sqrt(2 * a.mass * 1000.0)
    #a.momentum = np.array([0, 0, dp])
    t = np.zeros(len(atoms), int)
    t[n] = 1
    atoms.set_tags(t)
Пример #11
0
from MorseCalculator import MorsePotential
from ase.io import write, read
from ase import units
from ase.lattice.cubic import FaceCenteredCubic
from ase.md.verlet import VelocityVerlet

# Parameters for the Morse potential for Cu
D = 0.3429
r0 = 2.866
alpha = 1.3588

atoms = FaceCenteredCubic(latticeconstant=1.5,
                          symbol='Cu',
                          pbc=False,
                          size=(3, 3, 3))
atoms.center(vacuum=100)  #size of box

atoms.set_calculator(MorsePotential(D=D, alpha=alpha, r0=r0))

# write('relax.xyz', read('relax.traj@:')) # uncomment this line for Task 2

open('md.log', 'w').close()  # clean current log file
dyn = VelocityVerlet(atoms,
                     dt=1 * units.fs,
                     trajectory='md.traj',
                     logfile='md.log')

dyn.run(1000)
write('md.xyz', read('md.traj@:'))
# write('langevin.xyz', read('langevin.traj@:')) # uncomment this line for Task 3
Пример #12
0
symb = "Cu"
Z = data.atomic_numbers[symb]
a0 = data.reference_states[Z]['a']

# (100) oriented block
atoms = FaceCenteredCubic(size=(5,5,5), symbol="Cu", pbc=(1,1,0))
assert len(atoms) == 5*5*5*4
c = atoms.get_cell()
checkang(c[0], c[1], pi/2)
checkang(c[0], c[2], pi/2)
checkang(c[1], c[2], pi/2)
assert np.abs(5 * a0 - c[2,2]) < 1e-10

# Add vacuum in one direction
vac = 10.0
atoms.center(axis=2, vacuum=vac)
c = atoms.get_cell()
checkang(c[0], c[1], pi/2)
checkang(c[0], c[2], pi/2)
checkang(c[1], c[2], pi/2)
assert np.abs(4.5 * a0 + 2* vac - c[2,2]) < 1e-10

# Add vacuum in all directions
vac = 4.0
atoms.center(vacuum=vac)
c = atoms.get_cell()
checkang(c[0], c[1], pi/2)
checkang(c[0], c[2], pi/2)
checkang(c[1], c[2], pi/2)
assert np.abs(4.5 * a0 + 2* vac - c[0,0]) < 1e-10
assert np.abs(4.5 * a0 + 2* vac - c[1,1]) < 1e-10
Пример #13
0
def main(element, T_up, T_low, T_expect, bulkmodulus, makepot):
    def set_temp_fric(dyn, atoms):
        z = atoms.get_positions()[:,2]
        zmax = atoms.get_cell()[2,2]
        zmin = 0
        T = T_low + (T_up - T_low) * (z - zmin) / (zmax - zmin)
        dyn.set_temperature(T * units.kB)

    rnd = world.sum(random.randint(0,2**32)) # Insures the same number on all nodes.
    prefix = "melt-%s-%s" % (element, hex(rnd)[2:])
    if master:
        print "Using output directory", prefix
        os.mkdir(prefix)
    else:
        while not os.path.exists(prefix):
            time.sleep(1)
    if master:
        atoms = FaceCenteredCubic(symbol=element, size=size, pbc=(True, True, False))
        atoms.center(vacuum=10.0, axis=2)
    else:
        atoms = None
    atoms = MakeParallelAtoms(atoms, cpulayout1)
    print world.rank, '-', len(atoms), atoms.get_number_of_atoms()
    atoms.set_calculator(makepot())
    #view(atoms)
    
    dyn = Langevin(atoms, 5*units.fs, 0.0, friction)
    logger = MDLogger(dyn, atoms, prefix+'/Melt-phase1.log', stress=True, peratom=True)
    dyn.attach(logger, interval=100)
    set_temp_fric(dyn, atoms)
    unstress = Inhomogeneous_NPTBerendsen(atoms, 50*units.fs, 0, taup=500*units.fs,
                                          compressibility=1/bulkmodulus)
    dyn.attach(unstress.scale_positions_and_cell, interval=10)
    #traj = PickleTrajectory("melting-phase1.traj", "w", atoms)
    fn1 = prefix + "/Melt-phase1.bundle" 
    if master:
        print "Opening file", fn1
    traj = BundleTrajectory(fn1, "w", atoms, split=True)
    dyn.attach(traj, interval=500)
    
    therm = Thermometer(atoms, prefix+"/TempProfile-phase1.dat")
    dyn.attach(therm.update, interval=500)
    
    for i in range(steps1 / 100):
        dyn.run(100)
        set_temp_fric(dyn, atoms)
    if master:
        print "Closing file", fn1
    traj.close()
    del traj, atoms
    
    # Reread the bundle
    atoms = BundleTrajectory(fn1).get_atoms(-1, cpulayout2)
    atoms.set_calculator(makepot())
    dyn = VelocityVerlet(atoms, 5*units.fs)
    logger = MDLogger(dyn, atoms, prefix+'/PtMelt-phase2.log', stress=True, peratom=True)
    dyn.attach(logger, interval=1000)
    unstress = Inhomogeneous_NPTBerendsen(atoms, 50*units.fs, 0,
                                          taup=5000*units.fs,
                                          compressibility=1/bulkmodulus)
    dyn.attach(unstress.scale_positions_and_cell, interval=10)
    fn2 = prefix + "/Melt-phase2.bundle" 
    if master:
        print "Opening file", fn2
    traj = BundleTrajectory(fn2, "w", atoms)
    dyn.attach(traj, interval=steps2/100)
    
    therm = Thermometer(atoms, prefix+"/TempProfile-phase2.dat")
    dyn.attach(therm.update, interval=steps2/10)
    
    dyn.run(steps2 - takedata)
    therm2 = AveragingThermometer(atoms)
    dyn.attach(therm2.update, interval=100)
    dyn.run(takedata)  # Run the last part
    T = therm2.get_temp()
    if master:
        print "Melting temperature:", T
    ReportTest("Melting temperature", T, T_expect, 3)
    if cleanup:
        world.barrier()
        # Cleanup may fail due to the directory not being updated from
        # writes on the other nodes.  Wait for NFS file system.
        time.sleep(60)
        if master:
            shutil.rmtree(prefix)
    world.barrier()
    ReportTest.Summary()