Beispiel #1
0
def run(argv=None):
    if argv is None:
        argv = sys.argv[1:]
    elif isinstance(argv, str):
        argv = argv.split()
        
    parser = build_parser()
    opt, args = parser.parse_args(argv)
    
    if len(args) != 1:
        parser.error("incorrect number of arguments")
    name = args[0]

    if world.rank == 0:
        out = sys.stdout#open('%s-%s.results' % (name, opt.identifier), 'w')
    else:
        out = devnull

    a = None
    try:
        symbols = string2symbols(name)
    except ValueError:
        # name was not a chemical formula - must be a file name:
        atoms = read(name)
    else:
        if opt.crystal_structure:
            a = opt.lattice_constant
            if a is None:
                a = estimate_lattice_constant(name, opt.crystal_structure,
                                              opt.c_over_a)
                out.write('Using an estimated lattice constant of %.3f Ang\n' %
                          a)

            atoms = bulk(name, opt.crystal_structure, a, covera=opt.c_over_a,
                         orthorhombic=opt.orthorhombic, cubic=opt.cubic)
        else:
            try:
                # Molecule?
                atoms = molecule(name)
            except NotImplementedError:
                if len(symbols) == 1:
                    # Atom
                    atoms = Atoms(name)
                elif len(symbols) == 2:
                    # Dimer
                    atoms = Atoms(name, positions=[(0, 0, 0),
                                                   (opt.bond_length, 0, 0)])
                else:
                    raise ValueError('Unknown molecule: ' + name)

    if opt.magnetic_moment:
        magmom = opt.magnetic_moment.split(',')
        atoms.set_initial_magnetic_moments(np.tile(magmom,
                                                   len(atoms) // len(magmom)))

    if opt.repeat is not None:
        r = opt.repeat.split(',')
        if len(r) == 1:
            r = 3 * r
        atoms = atoms.repeat([int(c) for c in r])

    if opt.gui:
        view(atoms)
        return

    if opt.write_to_file:
        write(opt.write_to_file, atoms)
        return

    if opt.effective_medium_theory:
        Runner = EMTRunner
    else:
        Runner = GPAWRunner

    if opt.fit:
        strains = np.linspace(0.98, 1.02, 5)
    else:
        strains = None

    if opt.constrain_tags:
        tags = [int(t) for t in opt.constrain_tags.split(',')]
        constrain = FixAtoms(mask=[t in tags for t in atoms.get_tags()])
        atoms.constraints = [constrain]

    runner = Runner(name, atoms, strains, tag=opt.identifier,
                    clean=not opt.read,
                    fmax=opt.relax, out=out)

    if not opt.effective_medium_theory:
        # Import stuff that eval() may need to know:
        from gpaw.wavefunctions.pw import PW
        from gpaw.occupations import FermiDirac, MethfesselPaxton
            
        if opt.parameters:
            input_parameters = eval(open(opt.parameters).read())
        else:
            input_parameters = {}
        for key in defaults:
            value = getattr(opt, key)
            if value is not None:
                try:
                    input_parameters[key] = eval(value)
                except (NameError, SyntaxError):
                    input_parameters[key] = value

        runner.set_parameters(vacuum=opt.vacuum,
                              write_gpw_file=opt.write_gpw_file,
                              **input_parameters)

    runner.run()

    runner.summary(plot=opt.plot, a0=a)

    return runner
Beispiel #2
0
def build():
    p = OptionParser(usage='%prog  [options] [ads@]surf [output file]',
                     version='%prog 0.1',
                     description='Example ads/surf: fcc-CO@2x2Ru0001')
    p.add_option('-l', '--layers', type='int',
                 default=4,
                 help='Number of layers.')
    p.add_option('-v', '--vacuum', type='float',
                 default=5.0,
                 help='Vacuum.')
    p.add_option('-x', '--crystal-structure',
                 help='Crystal structure.',
                 choices=['sc', 'fcc', 'bcc', 'hcp'])
    p.add_option('-a', '--lattice-constant', type='float',
                 help='Lattice constant in Angstrom.')
    p.add_option('--c-over-a', type='float',
                 help='c/a ratio.')
    p.add_option('--height', type='float',
                 help='Height of adsorbate over surface.')
    p.add_option('--distance', type='float',
                 help='Distance between adsorbate and nearest surface atoms.')
    p.add_option('-M', '--magnetic-moment', type='float', default=0.0,
                 help='Magnetic moment.')
    p.add_option('-G', '--gui', action='store_true',
                 help="Pop up ASE's GUI.")

    opt, args = p.parse_args()

    if not 1 <= len(args) <= 2:
        p.error("incorrect number of arguments")

    if '@' in args[0]:
        ads, surf = args[0].split('@')
    else:
        ads = None
        surf = args[0]

    if surf[0].isdigit():
        i1 = surf.index('x')
        n = int(surf[:i1])
        i2 = i1 + 1
        while surf[i2].isdigit():
            i2 += 1
        m = int(surf[i1 + 1:i2])
        surf = surf[i2:]
    else:
        n = 1
        m = 1

    if surf[-1].isdigit():
        if surf[1].isdigit():
            face = surf[1:]
            surf = surf[0]
        else:
            face = surf[2:]
            surf = surf[:2]
    else:
        face = None

    Z = atomic_numbers[surf]
    state = reference_states[Z]

    if opt.crystal_structure:
        x = opt.crystal_structure
    else:
        x = state['symmetry'].lower()
    
    if opt.lattice_constant:
        a = opt.lattice_constant
    else:
        a = estimate_lattice_constant(surf, x, opt.c_over_a)

    if x == 'fcc':
        if face is None:
            face = '111'
        slab = fcc111(surf, (n, m, opt.layers), a, opt.vacuum)
        r = a / np.sqrt(2) / 2
    elif x == 'bcc':
        if face is None:
            face = '110'
        slab = bcc110(surf, (n, m, opt.layers), a, opt.vacuum)
        r = a * np.sqrt(3) / 4
    elif x == 'hcp':
        if face is None:
            face = '0001'
        if opt.c_over_a is None:
            c = np.sqrt(8 / 3.0) * a
        else:
            c = opt.c_over_a * a
        slab = hcp0001(surf, (n, m, opt.layers), a, c, opt.vacuum)
        r = a / 2
    else:
        raise NotImplementedError

    magmom = opt.magnetic_moment
    if magmom is None:
        magmom = {'Ni': 0.6, 'Co': 1.2, 'Fe': 2.3}.get(surf, 0.0)
    slab.set_initial_magnetic_moments([magmom] * len(slab))
    
    slab.pbc = 1

    name = '%dx%d%s%s' % (n, m, surf, face) 

    if ads:
        site = 'ontop'
        if '-' in ads:
            site, ads = ads.split('-')

        name = site + '-' + ads + '@' + name
        symbols = string2symbols(ads)
        nads = len(symbols) 
        if nads == 1:
            ads = Atoms(ads)
        else:
            ads = molecule(ads)

        add_adsorbate(slab, ads, 0.0, site)

        d = opt.distance
        if d is None:
            d = r + covalent_radii[ads[0].number] / 2
        
        h = opt.height
        if h is None:
            R = slab.positions
            y = ((R[:-nads] - R[-nads])**2).sum(1).min()**0.5
            print y
            h = (d**2 - y**2)**0.5
            print h
        else:
            assert opt.distance is None
        
        slab.positions[-nads:, 2] += h

    if len(args) == 2:
        write(args[1], slab)
    elif not opt.gui:
        write(name + '.traj', slab)
        
    if opt.gui:
        view(slab)
Beispiel #3
0
def build():
    p = OptionParser(usage='%prog  [options] [ads@]surf [output file]',
                     version='%prog 0.1',
                     description='Example ads/surf: fcc-CO@2x2Ru0001')
    p.add_option('-l', '--layers', type='int',
                 default=4,
                 help='Number of layers.')
    p.add_option('-v', '--vacuum', type='float',
                 default=5.0,
                 help='Vacuum.')
    p.add_option('-x', '--crystal-structure',
                 help='Crystal structure.',
                 choices=['sc', 'fcc', 'bcc', 'hcp'])
    p.add_option('-a', '--lattice-constant', type='float',
                 help='Lattice constant in Angstrom.')
    p.add_option('--c-over-a', type='float',
                 help='c/a ratio.')
    p.add_option('--height', type='float',
                 help='Height of adsorbate over surface.')
    p.add_option('--distance', type='float',
                 help='Distance between adsorbate and nearest surface atoms.')
    p.add_option('-M', '--magnetic-moment', type='float', default=0.0,
                 help='Magnetic moment.')
    p.add_option('-G', '--gui', action='store_true',
                 help="Pop up ASE's GUI.")
    p.add_option('-P', '--python', action='store_true',
                 help="Write Python script.")

    opt, args = p.parse_args()

    if not 1 <= len(args) <= 2:
        p.error("incorrect number of arguments")

    if '@' in args[0]:
        ads, surf = args[0].split('@')
    else:
        ads = None
        surf = args[0]

    if surf[0].isdigit():
        i1 = surf.index('x')
        n = int(surf[:i1])
        i2 = i1 + 1
        while surf[i2].isdigit():
            i2 += 1
        m = int(surf[i1 + 1:i2])
        surf = surf[i2:]
    else:
        n = 1
        m = 1

    if surf[-1].isdigit():
        if surf[1].isdigit():
            face = surf[1:]
            surf = surf[0]
        else:
            face = surf[2:]
            surf = surf[:2]
    else:
        face = None

    Z = atomic_numbers[surf]
    state = reference_states[Z]

    if opt.crystal_structure:
        x = opt.crystal_structure
    else:
        x = state['symmetry']
    
    if opt.lattice_constant:
        a = opt.lattice_constant
    else:
        a = estimate_lattice_constant(surf, x, opt.c_over_a)

    script = ['from ase.lattice.surface import ',
              'vac = %r' % opt.vacuum,
              'a = %r' % a]
    
    if x == 'fcc':
        if face is None:
            face = '111'
        slab = fcc111(surf, (n, m, opt.layers), a, opt.vacuum)
        script[0] += 'fcc111'
        script += ['slab = fcc111(%r, (%d, %d, %d), a, vac)' %
                   (surf, n, m, opt.layers)]
        r = a / np.sqrt(2) / 2
    elif x == 'bcc':
        if face is None:
            face = '110'
        if face == '110':
            slab = bcc110(surf, (n, m, opt.layers), a, opt.vacuum)
        elif face == '100':
            slab = bcc100(surf, (n, m, opt.layers), a, opt.vacuum)
        script[0] += 'bcc' + face
        script += ['slab = bcc%s(%r, (%d, %d, %d), a, vac)' %
                   (face, surf, n, m, opt.layers)]
        r = a * np.sqrt(3) / 4
    elif x == 'hcp':
        if face is None:
            face = '0001'
        if opt.c_over_a is None:
            c = np.sqrt(8 / 3.0) * a
        else:
            c = opt.c_over_a * a
        slab = hcp0001(surf, (n, m, opt.layers), a, c, opt.vacuum)
        script[0] += 'hcp0001'
        script += ['c = %r * a' % (c / a),
                   'slab = hcp0001(%r, (%d, %d, %d), a, c, vac)' %
                   (surf, n, m, opt.layers)]
        r = a / 2
    elif x == 'diamond':
        if face is None:
            face = '111'
        slab = diamond111(surf, (n, m, opt.layers), a, opt.vacuum)
        script[0] += 'diamond111'
        script += ['slab = diamond111(%r, (%d, %d, %d), a, vac)' %
                   (surf, n, m, opt.layers)]
        r = a * np.sqrt(3) / 8
    else:
        raise NotImplementedError

    magmom = opt.magnetic_moment
    if magmom is None:
        magmom = {'Ni': 0.6, 'Co': 1.2, 'Fe': 2.3}.get(surf, 0.0)
    slab.set_initial_magnetic_moments([magmom] * len(slab))
    if magmom != 0:
        script += ['slab.set_initial_magnetic_moments([%r] * len(slab))' %
                   magmom]
    
    slab.pbc = 1
    script += ['slab.pbc = True']
    
    name = '%dx%d%s%s' % (n, m, surf, face)

    if ads:
        site = 'ontop'
        if '-' in ads:
            site, ads = ads.split('-')

        name = site + '-' + ads + '@' + name
        symbols = string2symbols(ads)
        nads = len(symbols)
        if nads == 1:
            script[:0] = ['from ase import Atoms']
            script += ['ads = Atoms(%r)' % ads]
            ads = Atoms(ads)
        else:
            script[:0] = ['from ase.structure import molecule']
            script += ['ads = molecule(%r)' % ads]
            ads = molecule(ads)

        add_adsorbate(slab, ads, 0.0, site)

        d = opt.distance
        if d is None:
            d = r + covalent_radii[ads[0].number] / 2
        
        h = opt.height
        if h is None:
            R = slab.positions
            y = ((R[:-nads] - R[-nads])**2).sum(1).min()**0.5
            h = (d**2 - y**2)**0.5
        else:
            assert opt.distance is None
        
        slab.positions[-nads:, 2] += h

        script[1] += ', add_adsorbate'
        script += ['add_adsorbate(slab, ads, %r, %r)' % (h, site)]
        
    if len(args) == 2:
        write(args[1], slab)
        script[1:1] = ['from ase.io import write']
        script += ['write(%r, slab)' % args[1]]
    elif not opt.gui:
        write(name + '.traj', slab)
        script[1:1] = ['from ase.io import write']
        script += ['write(%r, slab)' % (name + '.traj')]
        
    if opt.gui:
        view(slab)
        script[1:1] = ['from ase.visualize import view']
        script += ['view(slab)']

    if opt.python:
        print('\n'.join(script))