Ejemplo n.º 1
0
def write_interstitials(structure, ttol=0.5):
    """ function to write POSCAR with interstitials

    Parameters:
        host = pylada structure object, bulk supercell recommended
        ttol = tolerance for finding interstitials

    Return:
        POSCAR file with interstitials, atom type "B"
    """

    struct = deepcopy(structure)
    ints = get_interstitials(struct, ttol)
    test_str = deepcopy(struct)

    for nn in range(len(ints)):
        test_str.add_atom(
            np.array(ints[nn])[0],
            np.array(ints[nn])[1],
            np.array(ints[nn])[2], 'B')

    print('Writing file POSCAR_ints with "B" type atoms as interstitials')

    with open("POSCAR_ints", "w") as file:
        write.poscar(test_str, file, vasp5=True)
Ejemplo n.º 2
0
def write_tcl_one(options, A, tag):
    """ write tcl file for viz in VMD """
    with open("POSCAR_A.%s" % tag, "w") as f:
        pcwrite.poscar(A, f, vasp5=True)
    write_xyz(options, A, "A.%s" % tag, options.output_tiles)

    fout = file("struct.%s.tcl" % tag, "w")
    center = False
    write_struct(fout, A, "A.%s.xyz" % tag, 0, center)
    fout.close()
Ejemplo n.º 3
0
def pylada_to_pmg(pylada_structure):
    '''
    Converts a pylada structure to a pymatgen structure via a temporary file

    :param pylada_structure: Pylada structure to convert
    :return: Structure
    '''
    with tempfile.NamedTemporaryFile() as tmp:
        name = tmp.name
        write.poscar(pylada_structure, name, vasp5=True)
        pymatgen_structure = Poscar.from_file(
            name).structure  # pymatgen.core.Structure
    return pymatgen_structure
Ejemplo n.º 4
0
def strainstructure(orgposcar, strain, direct):
    import os
    import numpy as np
    from pylada.crystal import write, read
    outdir = gettmpdir()
    tmp_file_name = "POSCAR"
    tmp_path = os.path.join(outdir, tmp_file_name)
    structure = read.poscar(orgposcar)
    a = np.array([1.0, 1.0, 1.0])
    if direct == "a":
        a[0] = strain
    elif direct == "b":
        a[1] = strain
    elif direct == "c":
        a[2] = strain
    A = np.diag(a)
    structure.cell = structure.cell * A
    for atom in structure:
        atom.pos = atom.pos * a
    write.poscar(structure, tmp_path, vasp5=True)
    return tmp_path
Ejemplo n.º 5
0
def write_tcl(options, A, B, pairs, tag="", center=False):
    """ write tcl file for viz in VMD """
    AA = deepcopy(A)
    BB = deepcopy(B)
    if pairs != None and len(pairs) > 0:
        for p in pairs:
            ia = p[0]
            ib = p[1]
            AA[ia].pos = p[3]
            BB[ib].pos = p[4]

    with open("POSCAR_A.%s" % tag, "w") as f:
        pcwrite.poscar(AA, f, vasp5=True)
    with open("POSCAR_B.%s" % tag, "w") as f:
        pcwrite.poscar(BB, f, vasp5=True)
    write_xyz(options, AA, "A.%s" % tag, options.output_tiles)
    write_xyz(options, BB, "B.%s" % tag, options.output_tiles)

    fout = file("plotpairs.%s.tcl" % tag, "w")
    write_struct(fout, AA, "A.%s.xyz" % tag, 0, center)
    write_struct(fout, BB, "B.%s.xyz" % tag, 1, center)

    linestr = "draw color green; graphics top line {%f %f %f} {%f %f %f} width 3 style dashed\n"
    #    sum = 0
    for p in pairs:
        print p
        ia = p[0]
        ib = p[1]
        p1 = AA.scale * AA[ia].pos
        p2 = BB.scale * BB[ib].pos
        ## double check!        print "TCL types: %s %s" % (A[ia].type, B[ib].type)
        #        val = npl.norm(np.array(p1)-np.array(p2))
        #        sum  += val
        #        print "write_tcl pairing: ", p1, p2, val
        fout.write(linestr % (p1[0], p1[1], p1[2], p2[0], p2[1], p2[2]))


#    print "write_tcl total pairing dist: ", sum

    fout.close()
Ejemplo n.º 6
0
def test_istruc():
  from collections import namedtuple
  from pickle import loads, dumps
  from os import remove
  from os.path import join, exists
  from shutil import rmtree
  from tempfile import mkdtemp
  from pylada.vasp.files import POSCAR, CONTCAR
  from pylada.vasp import Vasp
  from pylada.crystal import Structure, read, specieset, write
  from pylada.error import ValueError

  structure = Structure([[0, 0.5, 0.5],[0.5, 0, 0.5], [0.5, 0.5, 0]], scale=5.43, name='has a name')\
                       .add_atom(0,0,0, "Si")\
                       .add_atom(0.25,0.25,0.25, "Si")

  Extract = namedtuple("Extract", ['directory', 'success', 'structure'])
  a = Vasp()
  o = a._input['istruc']
  d = {'IStruc': o.__class__}

  directory = mkdtemp()
  try: 
    assert a.istruc == 'auto'
    assert o.output_map(vasp=a, outdir=directory, structure=structure) is None
    assert eval(repr(o), d).value == 'auto'
    assert loads(dumps(o)).value == 'auto'
    assert exists(join(directory, POSCAR))
    remove(join(directory, POSCAR))

    # check reading from outcar but only on success.
    a.restart = Extract(directory, False, structure.copy())
    a.restart.structure[1].pos[0] += 0.02
    assert a.istruc == 'auto'
    assert o.output_map(vasp=a, outdir=directory, structure=structure) is None
    assert exists(join(directory, POSCAR))
    other = read.poscar(join(directory, POSCAR), types=specieset(structure))
    assert abs(other[1].pos[0] - 0.25) < 1e-8
    assert abs(other[1].pos[0] - 0.27) > 1e-8
    # check reading from outcar but only on success.
    a.restart = Extract(directory, True, structure.copy())
    a.restart.structure[1].pos[0] += 0.02
    assert a.istruc == 'auto'
    assert o.output_map(vasp=a, outdir=directory, structure=structure) is None
    assert exists(join(directory, POSCAR))
    other = read.poscar(join(directory, POSCAR), types=specieset(structure))
    assert abs(other[1].pos[0] - 0.25) > 1e-8
    assert abs(other[1].pos[0] - 0.27) < 1e-8

    # Now check CONTCAR
    write.poscar(structure, join(directory, CONTCAR))
    assert a.istruc == 'auto'
    assert o.output_map(vasp=a, outdir=directory, structure=structure) is None
    assert exists(join(directory, POSCAR))
    other = read.poscar(join(directory, POSCAR), types=specieset(structure))
    assert abs(other[1].pos[0] - 0.25) < 1e-8
    assert abs(other[1].pos[0] - 0.27) > 1e-8

    # Check some failure modes.
    write.poscar(structure, join(directory, CONTCAR))
    structure[0].type = 'Ge'
    a.restart = None
    try: o.output_map(vasp=a, outdir=directory, structure=structure)
    except ValueError: pass
    else: raise Exception()
    structure[0].type = 'Si'
    structure.add_atom(0.25,0,0, 'Si')
    try: o.output_map(vasp=a, outdir=directory, structure=structure)
    except ValueError: pass
    else: raise Exception()

  finally: rmtree(directory)
Ejemplo n.º 7
0
def raw_anim(A, B, options):
    # just animate between A and B, straight up!
    ### this option is under development
    savedir = os.getcwd()
    os.chdir(options.trajdir)

    structure = pcread.poscar(options.A)
    structure = pcread.poscar(options.B)

    print "saving starting anim"
    Bpath = deepcopy(B)
    tag = "Bpath0"
    write_xyz(options, Bpath, tag, options.output_tiles)
    fout = file("%s.tcl" % tag, "w")
    write_struct(fout,
                 Bpath,
                 "%s.xyz" % tag,
                 0,
                 center=False,
                 bonds=True,
                 bond_len=options.bond_len)
    fout.close()

    # now write frames
    dt = 1.0 / (options.frames - 1)
    t = 0
    iter = 0
    eps = 1e-6
    curpos = []
    while t <= 1 + eps:
        Bpath = deepcopy(B)
        Bpath.cell = t * A.cell + (1.0 - t) * B.cell
        for i in range(len(apos)):
            pos = t * A[i].pos[i] + (1.0 - t) * B[i].pos[i]
            if (iter == 0):
                Bpath[i].pos = into_cell(
                    pos, Bpath.cell)  # then make sure it's _in_ the unit cell
                curpos.append(Bpath[i].pos)
            else:
                Bpath[i].pos = closest_to(pos, Bpath.cell, curpos[i])
                curpos[i] = Bpath[i].pos

        if (iter == 0):  ## testing/bug fixing
            from pylada.crystal import space_group, primitive
            from pylada.math import gruber
            Btest = primitive(Bpath)
            g = gruber(Btest.cell)
            print "src has cell:"
            print Btest.cell
            #            print g
            Btest = supercell(Btest, g)
            spacegroup = space_group(Btest)
            sg = spglib.get_spacegroup(Btest,
                                       symprec=1e-4,
                                       angle_tolerance=2.0)
            print "src has %d syms and sg %s" % (len(spacegroup), str(sg))
            Bstart = deepcopy(Bpath)

        sg = spglib.get_spacegroup(Bpath, symprec=1e-4, angle_tolerance=2.0)
        #        sg = spglib.get_spacegroup(Bpath, symprec=1e-1, angle_tolerance=10.0) ### debugging
        print t, sg, tag

        if (iter == options.frames - 1):  ## testing/bug fixing
            from pylada.crystal import space_group, primitive
            from pylada.math import gruber
            Btest = primitive(Bpath)
            g = gruber(Btest.cell)
            print "target has cell:"
            print Btest.cell
            #            print g
            Btest = supercell(Btest, g)
            spacegroup = space_group(Btest)
            sg = spglib.get_spacegroup(Btest,
                                       symprec=1e-4,
                                       angle_tolerance=2.0)
            print "target has %d syms and sg %s" % (len(spacegroup), str(sg))
            Bend = deepcopy(Bpath)

        tag = "traj.%d" % iter
        write_xyz(options, Bpath, tag, options.output_tiles)
        fout = file("%s.tcl" % tag, "w")
        write_struct(fout,
                     Bpath,
                     "%s.xyz" % tag,
                     0,
                     center=False,
                     bonds=True,
                     bond_len=options.bond_len)
        fout.close()

        # write poscar we can analyze later
        #        bigB = supercell(Bpath, np.dot(eye2,Bpath.cell))  # for writing a big poscar
        with open("%s.POSCAR" % tag, "w") as f:
            pcwrite.poscar(Bpath, f, vasp5=True)

        t += dt
        iter += 1

    os.chdir(savedir)
    if (options.verbose > 2):
        write_tcl(options, Bend, Bstart, pairs[1], "pairs")

    # some special work to verify we really arrived at B:


#    Borig = pcread.poscar(options.A)
#    M = np.dot(Borig.cell, npl.inv(Bpath.cell))
#    Bfinal = transform_cell(M,Bpath)
#    bigB = supercell(Bfinal, np.dot(eye2,Bfinal.cell))  ## this is a special "doubling" test
#    with open("final.POSCAR", "w") as f: pcwrite.poscar(bigB, f, vasp5=True)
#    with open("final.POSCAR", "w") as f: pcwrite.poscar(Bfinal, f, vasp5=True)
#    sg = spglib.get_spacegroup(Bfinal, symprec=1e-4, angle_tolerance=2.0)  ## this is "B in A coords"
#    print "spacegroup of final structure: ", sg
    sg = spglib.get_spacegroup(B, symprec=1e-4, angle_tolerance=2.0)
    print "spacegroup of initial structure (B, [Bflip in code]) ", sg
    sg = spglib.get_spacegroup(A, symprec=1e-4, angle_tolerance=2.0)
    print "spacegroup of target structure (A) ", sg
Ejemplo n.º 8
0
def make_anim(A, B, Tm, shift, pairs, options):
    # combined view of the unit call and atom transforms
    # A is target, B is src, after src has been rotated and its unit cell axes permuted so that they
    # "most align" with those of A.  Then transform is just two parts: first is unit cell Tform "Tm"
    # next is mapping in pairs
    ### no longer true: which is expressed in 3N-dim space as bigA.

    from copy import deepcopy
    from util import write_struct, write_xyz, transform_cell, write_tcl

    if options.verbose > 1:
        print "Exploring minimal path we have discovered..."
        # the results come out a little convoluated b/c of all the steps, so here we gather the
        # actual start and finish positions.

        details = False

        print B.cell
        print "maps to"
        print A.cell
        print "with internal atom shift"
        print shift
        print "and atom idx pairing"

    ppidx = pairs[0]
    ppos = pairs[1]
    ainv = npl.inv(A.cell)
    apos = []
    bpos = []
    for i in range(len(ppidx)):
        p = ppidx[i]
        q = ppos[i]
        print p, q  ##, into_cell(np.dot(B.cell, np.dot(ainv, q[4])), B.cell)
        apos.append(q[3])  # target atom position
        bpos.append(q[4])  # src atom position

    if (options.verbose > 2):
        print "and A is just"
        print A.cell
        for a in A:
            print a.pos, into_cell(a.pos, A.cell)
        print "and B is just"
        print B.cell
        for b in B:
            print b.pos, into_cell(b.pos, B.cell)

    if (not os.path.exists(options.trajdir)):
        os.mkdir(options.trajdir)

    savedir = os.getcwd()
    os.chdir(options.trajdir)

    if (options.verbose > 1):
        print "saving starting anim"
    Bpath = deepcopy(B)
    tag = "Bpath0"
    write_xyz(options, Bpath, tag, options.output_tiles)
    fout = file("%s.tcl" % tag, "w")
    write_struct(fout,
                 Bpath,
                 "%s.xyz" % tag,
                 0,
                 center=False,
                 bonds=True,
                 bond_len=options.bond_len)
    fout.close()

    # now write frames
    eye2 = 2.0 * np.identity(3)  # for writing a big cell if we want
    dt = 1.0 / (options.frames - 1)
    t = 0
    iter = 0
    eps = 1e-6
    curpos = []
    while t <= 1 + eps:

        Bpath = deepcopy(B)
        Bpath.cell = t * A.cell + (1.0 - t) * B.cell
        for i in range(len(apos)):
            p = t * apos[i] + (1.0 - t) * bpos[
                i]  # this is an abs position, but in A's frame of reference (both apos and bpos are created with
            # B.cell transformed to A.cell.  Here we are mapping to cells in between original B.cell and A.cell)
            # Note apos and bpos are not taken directly from A, B input cells but are part of the "pairing" data
            c = np.dot(ainv, p)  # so get the coords
            pos = np.dot(Bpath.cell,
                         c)  # and express it w.r.t. evolving Bpath frame
            if (iter == 0):
                Bpath[i].pos = into_cell(
                    pos, Bpath.cell)  # then make sure it's _in_ the unit cell
                curpos.append(Bpath[i].pos)
            else:
                Bpath[i].pos = closest_to(pos, Bpath.cell, curpos[i])
                curpos[i] = Bpath[i].pos

        if (iter == 0):  ## testing/bug fixing
            Bstart = deepcopy(Bpath)
            if (options.verbose > 2):
                from pylada.crystal import space_group, primitive
                from pylada.math import gruber
                Btest = primitive(Bpath)
                g = gruber(Btest.cell)
                print "src has primitive cell:"
                print Btest.cell
                #            print g
                Btest = supercell(Btest, g)
                spacegroup = space_group(Btest)
                sg = spglib.get_spacegroup(Btest,
                                           symprec=1e-4,
                                           angle_tolerance=2.0)
                print "src has %d syms and sg %s" % (len(spacegroup), str(sg))

        sg = spglib.get_spacegroup(Bpath, symprec=1e-4, angle_tolerance=2.0)
        #        sg = spglib.get_spacegroup(Bpath, symprec=1e-1, angle_tolerance=10.0) ### debugging
        if (options.verbose > 1):
            print t, sg, tag

        if (iter == options.frames - 1):  ## testing/bug fixing
            Bend = deepcopy(Bpath)
            if (options.verbose > 2):
                from pylada.crystal import space_group, primitive
                from pylada.math import gruber
                Btest = primitive(Bpath)
                g = gruber(Btest.cell)
                print "target has primitive cell:"
                print Btest.cell
                #            print g
                Btest = supercell(Btest, g)
                spacegroup = space_group(Btest)
                sg = spglib.get_spacegroup(Btest,
                                           symprec=1e-4,
                                           angle_tolerance=2.0)
                print "target has %d syms and sg %s" % (len(spacegroup),
                                                        str(sg))

        tag = "traj.%d" % iter
        write_xyz(options, Bpath, tag, options.output_tiles)
        fout = file("%s.tcl" % tag, "w")
        write_struct(fout,
                     Bpath,
                     "%s.xyz" % tag,
                     0,
                     center=False,
                     bonds=True,
                     bond_len=options.bond_len)
        fout.close()

        # write poscar we can analyze later
        #        bigB = supercell(Bpath, np.dot(eye2,Bpath.cell))  # for writing a big poscar
        with open("%s.POSCAR" % tag, "w") as f:
            pcwrite.poscar(Bpath, f, vasp5=True)

        t += dt
        iter += 1

    os.chdir(savedir)
    if (options.verbose > 2):
        write_tcl(options, Bend, Bstart, pairs[1], "pairs")

    # some special work to verify we really arrived at B:


#    Borig = pcread.poscar(options.A)
#    M = np.dot(Borig.cell, npl.inv(Bpath.cell))
#    Bfinal = transform_cell(M,Bpath)
#    bigB = supercell(Bfinal, np.dot(eye2,Bfinal.cell))  ## this is a special "doubling" test
#    with open("final.POSCAR", "w") as f: pcwrite.poscar(bigB, f, vasp5=True)
#    with open("final.POSCAR", "w") as f: pcwrite.poscar(Bfinal, f, vasp5=True)
#    sg = spglib.get_spacegroup(Bfinal, symprec=1e-4, angle_tolerance=2.0)  ## this is "B in A coords"
#    print "spacegroup of final structure: ", sg
    sg = spglib.get_spacegroup(B, symprec=1e-4, angle_tolerance=2.0)
    if (options.verbose > 0):
        print "spacegroup of initial structure (B, [Bflip in code]) ", sg
    sg = spglib.get_spacegroup(A, symprec=1e-4, angle_tolerance=2.0)
    if (options.verbose > 1):
        print "spacegroup of target structure (A) ", sg
a1 = [-d/2., d * (2+sqrt(3))/2., 0]
a2 = [d * (1+sqrt(3))/2., d * (3+sqrt(3))/2., 0]
a3 = [0,0,1]

l1 = d*sqrt(3)/2.
l2 = d*(sqrt(3)-1)/2.
h1 = 1.5*d 
h2 = d*(3+sqrt(3))/2.

structure = pyc.Structure(np.transpose([a1,a2,a3]), scale=1.0)
structure.add_atom(0,0,0, "Si")
structure.add_atom(0,d,0, "Si")
structure.add_atom(l1, h1, 0, "Si")
structure.add_atom(l2, h2, 0, "Si")

write.poscar(structure, file='fakeSiO2.POSCAR')
write_xyz(None, structure, 'fakeSiO2', 6)
###############

hn1 = -sqrt(3)/2. * d
h0 = 0
h1 = d
h2 = 1.5*d
h3 = (2+sqrt(3))/2. * d
h4 = (3+sqrt(3))/2. * d
h5 = (5+sqrt(3))/2. * d
h6 = (5+2*sqrt(3))/2. * d
h7 = (6+sqrt(3))/2. * d
h8 = (6+2*sqrt(3))/2. * d

l0 = 0
Ejemplo n.º 10
0
            slab = minimize_broken_bonds(bulk=bulk,slab=slab,vacuum=vacuum,charge=charge,minimize_total=True)

        except AssertionError:
            print("Charges do not sum up to zero for %s, the charges are:"%(files[f]), charge)
            print("Going to the next structure.")
            break
        # print("Done with the supercell construction, now shaping it")
        
        cell=transpose(slab.cell)
        cell[2][0]=0.
        cell[2][1]=0.
        slab.cell=transpose(cell)
        r=diag([1,1,1])
        slab=supercell(slab,dot(slab.cell,r))
        
        write.poscar(structure=slab,file=outdir_cur + '/POSCAR_%s%s%s_%slay_%svac' %(miller[0],miller[1],miller[2],nlayers,vacuum),vasp5=True)
        
        file.write('% 2i  % 2i  % 2i    broken_bonds %2.4f %2.4f polar=%s\n' %(miller[0],miller[1],miller[2],count_broken_bonds(bulk=bulk,slab=slab),count_broken_bonds_per_area(bulk=bulk,slab=slab),is_polar(slab=slab,charge=charge)))
        file.flush()

    else:
        file.write('DONE %d\n'%(miller_bounds))
        file.flush()
        file.close()
        print("%s on core %d: DONE"%(files[f], rank))
        continue

    file.write('FAILED\n')
    file.flush()
    file.close()
    print("%s on core %d: FAILED"%(files[f], rank))
Ejemplo n.º 11
0
def make_surfaces_to_pylada(root, bulk_structure, incar_settings=None, label='', depth=8, frozen_depth=2, override=[], kpt_modifier=1):
    '''

    :param root: root directory of run
    :param bulk_structure: pylada bulk strucutre
    :param incar_settings: location of INCAR.defaults
    :return:
    '''
    from pylada.crystal import write
    from Generate_Surface import Generate_Surface
    from Helpers import pyl_to_pmg, pmg_to_pyl
    from Generate_Surface import get_bottom, get_SD_along_vector
    # small_surfaces = Generate_Surface(pyl_to_pmg(bulk_structure), 1, 1, 1, 3, vacuum=8, orth=True)
    for i, surface in enumerate(Generate_Surface(pyl_to_pmg(bulk_structure), 1, 1, 1, depth, vacuum=8, orth=False)):
        # Frozen Surface
        # surface_small = small_surfaces[i]
        surf_folder = root / label / str(i).zfill(2)
        surf_folder.functional = WSBulkToFrozenSurfacePBE(Vasp(), bulk_structure=bulk_structure,
                                                          incar_settings=incar_settings, override=override,
                                                          kpt_modifier=kpt_modifier)
        surf_folder.params['structure'] = pmg_to_pyl(surface).copy()
        os.makedirs(surf_folder.name[1:], exist_ok=True)
        surface.to('poscar', os.path.join(surf_folder.name[1:], 'surface.vasp'))
        with open(os.path.join(surf_folder.name[1:], 'DATABASE'), 'w') as f:
            f.write('''
surface
surface_cut {}
surface_termination  {}
convergence_study
convergence_type surface
misc_labels {}
'''.format(i, 'None', label))

        # Frozen Surfaces

        for frozen_region in ['top', 'bottom']:

            froz_folder = surf_folder / frozen_region
            froz_folder.functional = WSBulkToSurfacePBE(Vasp(), bulk_structure=bulk_structure,
                                                        incar_settings=incar_settings, override=override,
                                                        kpt_modifier=kpt_modifier)

            surface_frozen = surface.copy()
            # print(surface_frozen)
            sd = get_SD_along_vector(surface_frozen, 2, get_bottom(surface_frozen, length=frozen_depth, region=frozen_region))
            # Poscar(surface_frozen, selective_dynamics=sd).write_file(os.path.join(froz_folder.name[1:], 'surface.vasp'))
            surface_frozen_pyl = pmg_to_pyl(surface_frozen)
            # sd_small = get_SD_along_vector(surface_frozen, frozen_depth, get_bottom(surface_frozen, region=frozen_region))
            for (atom, sd) in zip(surface_frozen_pyl, sd):
                if sd[0]:
                    atom.freeze = 'xyz'
            os.makedirs(froz_folder.name[1:], exist_ok=True)
            write.poscar(surface_frozen_pyl, os.path.join(froz_folder.name[1:], 'surface.vasp'), vasp5=True)
            froz_folder.params['structure'] = surface_frozen_pyl.copy()
            os.makedirs(froz_folder.name[1:], exist_ok=True)
            with open(os.path.join(froz_folder.name[1:], 'DATABASE'), 'w') as f:
                f.write('''
surface
surface_cut {}
surface_termination  {}
misc_labels {}
'''.format(i, frozen_region, label))
Ejemplo n.º 12
0
def test_istruc():
    from collections import namedtuple
    from pickle import loads, dumps
    from os import remove
    from os.path import join, exists
    from shutil import rmtree
    from tempfile import mkdtemp
    from pylada.vasp.files import POSCAR, CONTCAR
    from pylada.vasp import Vasp
    from pylada.crystal import Structure, read, specieset, write
    from pylada.error import ValueError

    structure = Structure([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]], scale=5.43, name='has a name')\
        .add_atom(0, 0, 0, "Si")\
        .add_atom(0.25, 0.25, 0.25, "Si")

    Extract = namedtuple("Extract", ['directory', 'success', 'structure'])
    a = Vasp()
    o = a._input['istruc']
    d = {'IStruc': o.__class__}

    directory = mkdtemp()
    try:
        assert a.istruc == 'auto'
        assert o.output_map(vasp=a, outdir=directory,
                            structure=structure) is None
        assert eval(repr(o), d).value == 'auto'
        assert loads(dumps(o)).value == 'auto'
        assert exists(join(directory, POSCAR))
        remove(join(directory, POSCAR))

        # check reading from outcar but only on success.
        a.restart = Extract(directory, False, structure.copy())
        a.restart.structure[1].pos[0] += 0.02
        assert a.istruc == 'auto'
        assert o.output_map(vasp=a, outdir=directory,
                            structure=structure) is None
        assert exists(join(directory, POSCAR))
        other = read.poscar(join(directory, POSCAR),
                            types=specieset(structure))
        assert abs(other[1].pos[0] - 0.25) < 1e-8
        assert abs(other[1].pos[0] - 0.27) > 1e-8
        # check reading from outcar but only on success.
        a.restart = Extract(directory, True, structure.copy())
        a.restart.structure[1].pos[0] += 0.02
        assert a.istruc == 'auto'
        assert o.output_map(vasp=a, outdir=directory,
                            structure=structure) is None
        assert exists(join(directory, POSCAR))
        other = read.poscar(join(directory, POSCAR),
                            types=specieset(structure))
        assert abs(other[1].pos[0] - 0.25) > 1e-8
        assert abs(other[1].pos[0] - 0.27) < 1e-8

        # Now check CONTCAR
        write.poscar(structure, join(directory, CONTCAR))
        assert a.istruc == 'auto'
        assert o.output_map(vasp=a, outdir=directory,
                            structure=structure) is None
        assert exists(join(directory, POSCAR))
        other = read.poscar(join(directory, POSCAR),
                            types=specieset(structure))
        assert abs(other[1].pos[0] - 0.25) < 1e-8
        assert abs(other[1].pos[0] - 0.27) > 1e-8

        # Check some failure modes.
        write.poscar(structure, join(directory, CONTCAR))
        structure[0].type = 'Ge'
        a.restart = None
        try:
            o.output_map(vasp=a, outdir=directory, structure=structure)
        except ValueError:
            pass
        else:
            raise Exception()
        structure[0].type = 'Si'
        structure.add_atom(0.25, 0, 0, 'Si')
        try:
            o.output_map(vasp=a, outdir=directory, structure=structure)
        except ValueError:
            pass
        else:
            raise Exception()

    finally:
        rmtree(directory)
def save_struct(options, A, tag):
    print "tag ", tag
    pcwrite.poscar(A, "%s.%s" % (options.A, tag), vasp5=True)
    write_tcl_one(options, A, tag)