コード例 #1
0
ファイル: gauss.py プロジェクト: jminuse/smrff
def PbCl2_2_new_bad_vac():
	for i in range(20):
		name = 'PbCl2_2_new_bad%d_vac' % i
		print 'Reading ' + name
		atoms=files.read_xyz('gaussian/'+name+'.xyz' )
		procs = Process(target=run_PbCl2_2_new_bad_vac, args=(i,atoms))
		procs.start()
コード例 #2
0
ファイル: gauss.py プロジェクト: jminuse/smrff
def from_md():
	frames = files.read_xyz('out.xyz')
	#g09.job('PbI2_PbI2_def2SVP', 'HSEH1PBE/Def2SVP Opt SCRF(Solvent=Water)', frames[1], queue=None, force=True).wait()
	shutil.copyfile('gaussian/PbI2_PbI2.cml', 'gaussian/PbI2_PbI2_def2SVP.cml')
	for i,atoms in enumerate(frames[2:]):
		#print 'Running %d' % i
		#g09.job('PbI2_PbI2_%d_def2SVP' % i, 'HSEH1PBE/Def2SVP Force SCRF(Solvent=Water)', atoms, queue=None).wait()
		shutil.copyfile('gaussian/PbI2_PbI2.cml', 'gaussian/PbI2_PbI2_%d_def2SVP.cml' % i)
コード例 #3
0
ファイル: gauss.py プロジェクト: jminuse/smrff
def PbCl2_reax_min():
	frames = files.read_xyz('lammps/testing.xyz')
	#g09.job('PbI2_PbI2_def2SVP', 'HSEH1PBE/Def2SVP Opt SCRF(Solvent=Water)', frames[1], queue=None, force=True).wait()
	shutil.copyfile('gaussian/PbCl2_rot80_vac.cml', 'gaussian/PbCl2_reax_min.cml')
	for i,atoms in enumerate(frames[2:]):
		procs = Process(target=run_PbCl2_reax_min, args=(i,atoms))
		procs.start()
		print 'Running %d' % i
コード例 #4
0
ファイル: mcsmrff_utils.py プロジェクト: hherbol/Grad-MCSMRFF
def read_dump_PbCl3MA(fptr, persist=False):
    frames = read_dump_worker(fptr, data=["type", "xu", "yu", "zu"])

    swap = {1: "Pb", 2: "Cl", 3: "N", 4: "C", 5: "H", 6: "H"}

    for i, frame in enumerate(frames):
        for j, atom in enumerate(frame):
            frames[i][j][0] = swap[atom[0]]

    frames_to_xyz("tmp_read_dump.xyz", frames)
    frames = files.read_xyz("tmp_read_dump.xyz")

    if not persist:
        os.system("rm tmp_read_dump.xyz")

    return frames
コード例 #5
0
ファイル: mcsmrff_utils.py プロジェクト: hherbol/Grad-MCSMRFF
def read_dump_PbCl3MA(fptr, persist=False):
    frames = read_dump_worker(fptr, data=["type", "xu", "yu", "zu"])

    swap = {1: "Pb", 2: "Cl", 3: "N", 4: "C", 5: "H", 6: "H"}

    for i, frame in enumerate(frames):
        for j, atom in enumerate(frame):
            frames[i][j][0] = swap[atom[0]]

    frames_to_xyz("tmp_read_dump.xyz", frames)
    frames = files.read_xyz("tmp_read_dump.xyz")

    if not persist:
        os.system("rm tmp_read_dump.xyz")

    return frames
コード例 #6
0
ファイル: gauss.py プロジェクト: jminuse/smrff
def PbCl2_2_new_vac():
	for i in range(30):
		atoms=files.read_xyz('gaussian/PbCl2_2_new_vac.xyz')
		xs=random.random();ys=random.random();zs=random.random();rand=random.random()
		for a in atoms[:3]:
			if rand<.33:
				a.x+=xs
				a.y+=ys
				a.z+=zs
			elif rand < .66:
				a.x-=xs
				a.y+=ys
				a.z+=zs
			else:
				a.x-=xs
				a.y-=ys
				a.z+=zs
		procs = Process(target=run_PbCl2_2_new_vac, args=(i,atoms))
		procs.start()
コード例 #7
0
ファイル: neb_demo.py プロジェクト: hherbol/ase_orca
def method_CLANCELOT(opt_method="LBFGS"):
    from files import read_xyz, write_xyz
    import neb
    from units import convert, convert_energy

    FPTR = "./../xyz/CNH_HCN.xyz"
    frames = read_xyz(FPTR)
    route = '! HF-3c'

    if RIGID_ROTATION:
        is_on = "ON"
    else:
        is_on = "OFF"

    print("\nRUNNING CLANCELOT SIMULATION WITH RIGID_ROTATION %s...\n" % is_on)

    run_name = 'CNH_HCN_c_' + opt_method
    new_opt_params = {
        'step_size': ALPHA,
        'step_size_adjustment': 0.5,
        'max_step': MAX_STEP,
        'linesearch': 'backtrack',
        'accelerate': True,
        'reset_step_size': 5,
        'g_rms': convert("eV/Ang", "Ha/Ang", 0.03),
        'g_max': convert("eV/Ang", "Ha/Ang", FMAX)
    }

    opt = neb.NEB(run_name,
                  frames,
                  route,
                  k=convert_energy("eV", "Ha", 0.1),
                  opt=opt_method,
                  new_opt_params=new_opt_params)
    output = opt.optimize()
    frames = output[-1]

    write_xyz(frames, "CNH_HCN_opt_%s" % opt_method)

    print("\nDONE WITH CLANCELOT SIMULATION...\n")
コード例 #8
0
ファイル: run_lammps.py プロジェクト: jminuse/smrff
pbi2 = utils.Molecule('cml/PbI2', extra_parameters=extra)
pbi2.bonds = []
pbi2.angles = []

system.add(pbi2, 0, 2)

os.chdir('lammps')
files.write_lammps_data(system)

commands = ('''units real
atom_style full
pair_style tersoff

read_data	'''+system.name+'''.data

pair_coeff * * tersoff SiO.tersoff O Si

dump 1 all xyz 1000 '''+system.name+'''.xyz

min_style fire
minimize 0.0 1.0e-8 1000 100000
''').splitlines()
lmp = lammps()
for line in commands:
	lmp.command(line)

xyz = files.read_xyz(system.name+'.xyz')[-1] # take last frame from LAMMPS job
for i,a in enumerate(system.atoms):
	a.x, a.y, a.z = xyz[i].x, xyz[i].y, xyz[i].z

コード例 #9
0
ファイル: orca_mep.py プロジェクト: aaronchen0316/squid
def electrostatic_potential_cubegen(fname,
                                    npoints=80,
                                    orca4=sysconst.use_orca4):
    '''
    '''
    os.chdir("orca/%s" % fname)
    # First we ensure the density matrix file (scfp) was generated
    cmds = [1, 2, 'y', 5, 7, 10, 11]
    fptr = open("tmp.plt", 'w')
    for cmd in cmds:
        fptr.write("%s\n" % str(cmd))
    fptr.close()

    orcaPath = sysconst.orca_path
    if orca4:
        orcaPath = sysconst.orca4_path

    print("GENERATING CUBE FILE...\n")

    #os.system("%s_plot orca/%s/%s.orca.gbw -i < tmp.plt"
    #          % (orcaPath, fname, fname))

    os.system("%s_plot %s.orca.gbw -i < tmp.plt" % (orcaPath, fname))
    os.system("rm tmp.plt")

    print("DONE")

    pot_name = "%s.orca.scfp" % fname
    #shutil.move(pot_name, "orca/%s/%s" % (fname, pot_name))

    rho_name = "%s.orca.eldens.cube" % fname
    #shutil.move(rho_name, "orca/%s/%s" % (fname, rho_name))

    # Shorten command for unit conversion
    conv = lambda x: units.convert_dist("Ang", "Bohr", x)

    # Read in atoms and set units to bohr
    atoms = files.read_xyz("%s.orca.xyz" % fname)
    #atoms = files.read_xyz("orca/%s/%s.orca.xyz" % (fname, fname))
    for a in atoms:
        a.x = conv(a.x)
        a.y = conv(a.y)
        a.z = conv(a.z)

    # Get range for grid, with some buffer
    buf = 7.0
    x_range = [
        conv(min([a.x for a in atoms]) - buf),
        conv(max([a.x for a in atoms]) + buf)
    ]
    y_range = [
        conv(min([a.y for a in atoms]) - buf),
        conv(max([a.y for a in atoms]) + buf)
    ]
    z_range = [
        conv(min([a.z for a in atoms]) - buf),
        conv(max([a.z for a in atoms]) + buf)
    ]

    # Open file for electrostatic potential
    pot = open("%s_pot.inp" % fname, 'w')
    #pot = open("orca/%s/%s_pot.inp" % (fname, fname), 'w')
    pot.write("{0:d}\n".format(npoints**3))
    for ix in np.linspace(x_range[0], x_range[1], npoints, True):
        for iy in np.linspace(y_range[0], y_range[1], npoints, True):
            for iz in np.linspace(z_range[0], z_range[1], npoints, True):
                pot.write("{0:12.6f} {1:12.6f} {2:12.6f}\n".format(ix, iy, iz))
    pot.close()

    # Use built in orca command to generate potential output from gbw file
    #cmd = "%s_vpot orca/%s/%s.orca.gbw orca/%s/%s.orca.scfp orca/%s/%s_pot.inp orca/%s/%s_pot.out"\
    cmd = "%s_vpot %s.orca.gbw %s.orca.scfp %s_pot.inp %s_pot.out"\
          % (orcaPath, fname, fname, fname, fname)
    os.system(cmd)

    # Read in the electrostatic potential
    vpot = read_vpot("%s_pot.out" % fname)
    #vpot = read_vpot("orca/%s/%s_pot.out" % (fname, fname))

    # Start generating the cube file
    cube = open("%s.orca.pot.cube" % fname, 'w')
    #cube = open("orca/%s/%s.orca.pot.cube" % (fname, fname), 'w')
    cube.write("Generated with ORCA\n")
    cube.write("Electrostatic potential for " + fname + "\n")
    cube.write("{0:5d}{1:12.6f}{2:12.6f}{3:12.6f}\n".format(
        len(atoms), x_range[0], y_range[0], z_range[0]))
    cube.write("{0:5d}{1:12.6f}{2:12.6f}{3:12.6f}\n".format(
        npoints, (x_range[1] - x_range[0]) / float(npoints - 1), 0.0, 0.0))
    cube.write("{0:5d}{1:12.6f}{2:12.6f}{3:12.6f}\n".format(
        npoints, 0.0, (y_range[1] - y_range[0]) / float(npoints - 1), 0.0))
    cube.write("{0:5d}{1:12.6f}{2:12.6f}{3:12.6f}\n".format(
        npoints, 0.0, 0.0, (z_range[1] - z_range[0]) / float(npoints - 1)))
    for a in atoms:
        index = units.elem_s2i(a.element)
        cube.write("{0:5d}{1:12.6f}{2:12.6f}{3:12.6f}{4:12.6f}\n".format(
            index, 0.0, a.x, a.y, a.z))

    m, n = 0, 0
    vpot = np.reshape(vpot, (npoints, npoints, npoints))
    for ix in range(npoints):
        for iy in range(npoints):
            for iz in range(npoints):
                cube.write("{0:14.5e}".format(vpot[ix][iy][iz]))
                m += 1
                n += 1
                if (n > 5):
                    cube.write("\n")
                    n = 0
            if n != 0:
                cube.write("\n")
                n = 0
    cube.close()

    os.chdir("../../")
コード例 #10
0
ファイル: mcsmrff_utils.py プロジェクト: hherbol/Grad-MCSMRFF
def pdf_metric(A,
               ref=None,
               persist=False,
               lammps_job=False,
               start=0.0,
               stop=10.0,
               step=0.1,
               cutoff=3.0,
               quanta=0.001,
               disregard=[]):
    # If we are checking a lammps job, grab the xyz file from
    # lammps/run_name/run_name.xyz
    if lammps_job is True:
        if A.endswith(".xyz"):
            A.split(".xyz")[0]
        if A.endswith(".dump"):
            A.split(".dump")[0]
        if A.endswith(".data"):
            A.split(".data")[0]
        A = read_dump_PbCl3MA("lammps/%s/%s2.dump" % (A, A))

    # If we passed a string, then read in the file
    if type(A) is str:
        if not A.endswith(".xyz"):
            A += ".xyz"
        A = files.read_xyz(A)

    # Assume reference is the first frame
    if ref is None:
        ref = A[0]
    else:
        raise Exception("This is not coded yet.")

    B = copy.deepcopy([A[0], A[-1]])
    # Remove anything in disregard
    for i, frame in enumerate(B):
        to_kill = []
        for j, atom in enumerate(frame):
            if atom.element in disregard:
                to_kill.append(j)
        to_kill = sorted(to_kill)[::-1]
        for k in to_kill:
            del B[i][k]

    pdf_ref = debyer.get_pdf(B[0],
                             persist=persist,
                             output="tmp_pdf_ref",
                             start=start,
                             stop=stop,
                             step=step,
                             cutoff=cutoff,
                             quanta=quanta)
    pdf_final = debyer.get_pdf(B[-1],
                               persist=persist,
                               output="tmp_pdf_final",
                               start=start,
                               stop=stop,
                               step=step,
                               cutoff=cutoff,
                               quanta=quanta)
    files.write_xyz([B[0], B[-1]], "pdf_metric_debug")

    # Split lists
    pdf_ref = zip(*pdf_ref)
    pdf_final = zip(*pdf_final)

    difference = [(a - b)**2 for a, b in zip(pdf_ref[1], pdf_final[1])]
    rms = (np.asarray(difference).sum() / float(len(difference)))**0.5

    if not persist:
        os.system("rm pdf_metric_debug.xyz")

    return rms, [pdf_ref, pdf_final]
コード例 #11
0
                else:
                    if L_s2n:
                        return 'S' + str(sn_axis), max_cn_axis
                    else:
                        return 'C' + str(max_cn_axis), max_cn_axis
    else:
        if L_cs:
            return 'Cs', 1
        else:
            if L_i:
                return 'Ci', 1
            else:
                return 'C1', 1

if __name__ == '__main__':

    import sys
    list_xyz = sys.argv[1:]
    if list_xyz == []:
        print "Execute as pgs.py  file1.xyz [file2.xyz [file3.xyz]]"
        exit()

    import files as ff
    for filexyz in list_xyz:
        xcc, symbs, masses = ff.read_xyz(filexyz)
        from fncs import symbols2atonums
        atonums = symbols2atonums(symbs)
        pg, sigma = get_pgs(atonums, masses, xcc)
        print "Point group of symmetry   :", pg
        print "Rotational symmetry number:", sigma
コード例 #12
0
ファイル: utils.py プロジェクト: hherbol/clancelot
def pretty_xyz(name,R_MAX=1,F_MAX=50,PROCRUSTS=False,outName=None,write_xyz=False,verbose=False):
	#----------
	# name = Name of xyz file to read in
	# R_MAX = maximum motion per frame
	# F_MAX = maximum number of frames allowed
	# PROCRUSTES = Center frames or not
	# outName = If you wish to output to file, give a name. Defalt name is 'pretty_xyz'
	# write_xyz = Write to file. Default False
	# Verbose = Outputing what pretty_xyz is doing as it goes
	#----------

	from copy import deepcopy
	
	# Get data as either frames or a file
	if type(name)==type(''): frames = files.read_xyz(name)
	elif type(name)==type([]): frames = name
	else:
		print "Error - Invalid name input.  Should be either the name of an xyz file or a list.", sys.exc_info()[0]
		exit()

	# Loop till we're below R_MAX
	while 1:
		# Find largest motion_per_frame
		if PROCRUSTS: procrustes(frames)
		tmp = motion_per_frame(frames)
		i = tmp.index(max(tmp))

		# Check if we're done
		r2 = max(tmp)
		if r2 < R_MAX: break

		if len(frames) > F_MAX:
			print "-------------------------------------------------------"
			print tmp
			print "-------------------------------------------------------"
			print "\n\nError - Could not lower motion below %lg in %d frames." % (R_MAX,F_MAX), sys.exc_info()[0]
			exit()
		else:
			if verbose: print "Currently Frames = %d\tr2 = %lg" % (len(frames),r2)

		# Now, split the list, interpolate, and regenerate
		if i > 0 and i < len(frames) - 1:
			f_low = deepcopy(frames[:i])
			f_high = deepcopy(frames[i+1:])
			f_mid = interpolate(frames[i-1],frames[i+1],3)
			frames = f_low + f_mid + f_high
		elif i == 0:
			f_low = deepcopy(frames[i])
			f_mid = interpolate(frames[i],frames[i+1],3)
			f_high = deepcopy(frames[i+1:])
			frames = [f_low] + f_mid + f_high
		else:
			f_low = deepcopy(frames[:i])
			f_mid = interpolate(frames[i-1],frames[i],3)
			f_high = deepcopy(frames[i])
			frames = f_low + f_mid + [f_high]

		if verbose: print "\tInterpolated %d,%d ... %lg" % (index-1,index+1,max(motion_per_frame(frames)))

	if PROCRUSTS: procrustes(frames)

	if write_xyz: files.write_xyz(frames,'pretty_xyz' if outName==None else outName)
	else: return frames
コード例 #13
0
ファイル: mcsmrff_utils.py プロジェクト: hherbol/Grad-MCSMRFF
def pdf_metric(A, ref=None, persist=False, lammps_job=False, start=0.0,
               stop=10.0, step=0.1, cutoff=3.0, quanta=0.001, disregard=[]):
    # If we are checking a lammps job, grab the xyz file from
    # lammps/run_name/run_name.xyz
    if lammps_job is True:
        if A.endswith(".xyz"):
            A.split(".xyz")[0]
        if A.endswith(".dump"):
            A.split(".dump")[0]
        if A.endswith(".data"):
            A.split(".data")[0]
        A = read_dump_PbCl3MA("lammps/%s/%s2.dump" % (A, A))

    # If we passed a string, then read in the file
    if type(A) is str:
        if not A.endswith(".xyz"):
            A += ".xyz"
        A = files.read_xyz(A)

    # Assume reference is the first frame
    if ref is None:
        ref = A[0]
    else:
        raise Exception("This is not coded yet.")

    B = copy.deepcopy([A[0], A[-1]])
    # Remove anything in disregard
    for i, frame in enumerate(B):
        to_kill = []
        for j, atom in enumerate(frame):
            if atom.element in disregard:
                to_kill.append(j)
        to_kill = sorted(to_kill)[::-1]
        for k in to_kill:
            del B[i][k]

    pdf_ref = debyer.get_pdf(B[0],
                             persist=persist,
                             output="tmp_pdf_ref",
                             start=start,
                             stop=stop,
                             step=step,
                             cutoff=cutoff,
                             quanta=quanta)
    pdf_final = debyer.get_pdf(B[-1],
                               persist=persist,
                               output="tmp_pdf_final",
                               start=start,
                               stop=stop,
                               step=step,
                               cutoff=cutoff,
                               quanta=quanta)
    files.write_xyz([B[0], B[-1]], "pdf_metric_debug")

    # Split lists
    pdf_ref = zip(*pdf_ref)
    pdf_final = zip(*pdf_final)

    difference = [(a - b)**2 for a, b in zip(pdf_ref[1], pdf_final[1])]
    rms = (np.asarray(difference).sum() / float(len(difference)))**0.5

    if not persist:
        os.system("rm pdf_metric_debug.xyz")

    return rms, [pdf_ref, pdf_final]
コード例 #14
0
ファイル: gauss.py プロジェクト: jminuse/smrff
def lead_chloride_crystal():
	frames = files.read_xyz('xyz/leadChloride.xyz')
	g09.job()
コード例 #15
0
ファイル: CNK_KCN_BFGS.py プロジェクト: jminuse/clancelot
import sys
import files, neb

fptr = 'CNK_KCN'
frames = files.read_xyz('/fs/home/hch54/clancelot/unit_tests/neb/xyz/'+fptr+'.xyz')
opt = 'BFGS'
route = '! M062X def2-TZVP Grid3 FinalGrid5'

run_name = fptr[:fptr.find('.xyz')] + '_' + opt
neb.neb(run_name, frames, route, opt=opt, maxiter=1000, gtol=0.00183726383934, DFT='orca', alpha=0.1, dt=0.1, mem=40, Nmax=20)
コード例 #16
0
ファイル: gauss.py プロジェクト: jminuse/smrff
def run_cl2_pair(i):
	frame = files.read_xyz('pbcl2.xyz')
	frame[0].y -= i*0.4
	name = 'PbCl2_c_%d_vac' % i
	g09.job(name, 'HSEH1PBE/Def2TZVP Force SCF=(IntRep,QC)', frame, queue=None, force=True)
コード例 #17
0
ファイル: gauss.py プロジェクト: jminuse/smrff
def PbCl2_2():
	atoms=files.read_xyz('gaussian/PbCl2_2.xyz')
	g09.job('PbCl2t_2_def2SVP', 'HSEH1PBE/Def2SVP Force SCRF(Solvent=Water)', atoms, queue=None,force=True).wait()
	shutil.copyfile('gaussian/PbCl2_2.cml', 'gaussian/PbCl2t_2_def2SVP.cml')
コード例 #18
0
import sys
import files, neb

fptr = 'CNLi_LiCN'
frames = files.read_xyz('/fs/home/hch54/clancelot/unit_tests/neb/xyz/' + fptr +
                        '.xyz')
opt = 'BFGS'
route = '! RI-B2PLYP D3BJ def2-TZVP def2-TZVP/C Grid3 FinalGrid5'

run_name = fptr[:fptr.find('.xyz')] + '_' + opt
neb.neb(run_name,
        frames,
        route,
        opt=opt,
        maxiter=1000,
        gtol=0.00183726383934,
        DFT='orca',
        alpha=0.1,
        dt=0.1,
        mem=40,
        Nmax=20)
コード例 #19
0
def job(run_name,
        atoms,
        ecut,
        ecutrho=None,
        atom_units="Ang",
        route=None,
        pseudopotentials=None,
        periodic_distance=15,
        dumps="dump End Ecomponents ElecDensity",
        queue=None,
        walltime="00:30:00",
        procs=1,
        threads=None,
        redundancy=False,
        previous=None,
        mem=2000,
        priority=None,
        xhost=None,
        slurm_allocation=sysconst.slurm_default_allocation):
    """
    Wrapper to submitting a JDFTx simulation.

    **Parameters**

        run_name: *str*
            Name of the simulation to be run.
        atoms: *list,* :class:`structures.Atom` *, or str*
            A list of atoms for the simulation.  If a string is passed, it is
            assumed to be an xyz file (relative or full path).  If None is passed,
            then it is assumed that previous was specified.
        ecut: *float*
            The planewave cutoff energy in Hartree.
        ecutrho: *float, optional*
            The charge density cutoff in Hartree.  By default this is 4 * ecut.
        atom_units: *str, optional*
            What units your atoms are in.  JDFTx expects bohr; however, typically
            most work in Angstroms.  Whatever units are converted to bohr here.
        route: *str, optional*
            Any additional script to add to the JDFTx simulation.
        pseudopotentials: *list, str, optional*
            The pseudopotentials to use in this simulation.  If nothing is passed,
            a default set of ultra-soft pseudo potentials will be chosen.
        periodic_distance: *float, optional*
            The periodic box distance in Bohr.
        dumps: *str, optional*
            The outputs for this simulation.
        queue: *str, optional*
            What queue to run the simulation on (queueing system dependent).
        procs: *int, optional*
            How many processors to run the simulation on.
        threads: *int, optional*
            How many threads to run the simulation on.  By default this is procs.
        redundancy: *bool, optional*
            With redundancy on, if the job is submitted and unique_name is on, then
            if another job of the same name is running, a pointer to that job will
            instead be returned.
        previous: *str, optional*
            Name of a previous simulation for which to try reading in
            information using the MORead method.
        mem: *float, optional*
            Amount of memory per processor that is available (in MB).
        priority: *int, optional*
            Priority of the simulation (queueing system dependent).  Priority
            ranges (in NBS) from a low of 1 (start running whenever) to a
            high of 255 (start running ASAP).
        xhost: *list, str or str, optional*
            Which processor to run the simulation on(queueing system
            dependent).
        slurm_allocation: *str, optional*
            Whether to use a slurm allocation for this job or not.  If so, specify the name.

    **Returns**

        job: :class:`jobs.Job`
            Teturn the job container.
    """

    if len(run_name) > 31 and queue is not None:
        raise Exception("Job name too long (%d) for NBS. \
Max character length is 31." % len(run_name))

    # Generate the orca input file
    os.system('mkdir -p jdftx/%s' % run_name)

    if previous is not None:
        shutil.copyfile("jdftx/%s/%s.xyz" % (previous, previous),
                        "jdftx/%s/%s.xyz" % (run_name, previous))
        shutil.copyfile("jdftx/%s/%s.xyz" % (previous, previous),
                        "jdftx/%s/%s.xyz" % (run_name, run_name))
        shutil.copyfile("jdftx/%s/%s.ionpos" % (previous, previous),
                        "jdftx/%s/%s.ionpos" % (run_name, previous))
        shutil.copyfile("jdftx/%s/%s.lattice" % (previous, previous),
                        "jdftx/%s/%s.lattice" % (run_name, previous))

    os.chdir('jdftx/%s' % run_name)

    # Start from a blank output file
    if os.path.isfile("%s.out" % run_name):
        os.system("mv %s.out %s_prev.out" % (run_name, run_name))

    if threads is None:
        threads = procs

    path_jdftx = sysconst.jdftx_path
    if path_jdftx.endswith("/"):
        path_jdftx = path_jdftx[:-1]

    path_jdftx_scripts = sysconst.jdftx_script_path
    if path_jdftx_scripts.endswith("/"):
        path_jdftx_scripts = path_jdftx_scripts[:-1]

    if atoms is not None:
        if not isinstance(atoms, str):
            for a in atoms:
                a.element = units.elem_i2s(a.element)
            files.write_xyz(atoms, "%s.xyz" % run_name)
        else:
            atoms = files.read_xyz(atoms)
            for a in atoms:
                a.element = units.elem_i2s(a.element)
            files.write_xyz(atoms, "%s.xyz" % run_name)

    if run_name.endswith(".xyz"):
        run_name = run_name.split(".xyz")[0]

    # NOTE! xyzToIonposOpt will convert xyz Angstroms to Bohr
    os.system("%s/xyzToIonposOpt %s.xyz %d > xyzToIonpos.log" %
              (path_jdftx_scripts, run_name, periodic_distance))

    previous_name = None
    if previous:
        previous_name = previous
        previous = "initial-state %s.$VAR" % previous

    # First, read in the xyz file to determine unique elements
    if pseudopotentials is None and atoms is not None:
        pseudopotentials = []
        elements = geometry.reduce_list([a.element.lower() for a in atoms])
        all_pps = [
            fname
            for fname in os.listdir("%s/pseudopotentials/GBRV" % path_jdftx)
            if fname.endswith("uspp") and "pbe" in fname
        ]
        for e in elements:
            potential_pps = []
            for pp in all_pps:
                if pp.startswith("%s_" % e):
                    potential_pps.append(pp)
            if len(potential_pps) < 1:
                raise Exception(
                    "Unable to automatically grab potential for element %s." %
                    e)
            else:
                potential_pps.sort(
                )  # In theory this should be the "largest" number based on the naming convention.
                pseudopotentials.append("GBRV/" + potential_pps[0])

    if atoms is None:
        pseudopotentials = '''ion-species GBRV/$ID_pbe_v1.2.uspp
ion-species GBRV/$ID_pbe_v1.01.uspp
ion-species GBRV/$ID_pbe_v1.uspp'''
    else:
        pseudopotentials = "\n".join(
            ["ion-species %s" % pp for pp in pseudopotentials])

    script = '''
# --------------- Molecular Structure ----------------

$$ATOMS$$
coords-type cartesian

$$PREVIOUS$$

# --------------- System Parameters ----------------

elec-cutoff $$ECUT$$ $$ECUTRHO$$

# Specify the pseudopotentials (this defines species O and H):
$$PSEUDOPOTENTIALS$$

# --------------- Outputs ----------------

dump-name $$NAME$$.$VAR              #Filename pattern for outputs
$$DUMPS$$  #Output energy components and electron density at the end
'''

    atom_str = '''include $$NAME$$.lattice
include $$NAME$$.ionpos'''

    if atoms is not None:
        atom_str = atom_str.replace("$$NAME$$", run_name)
    else:
        if previous_name is None:
            raise Exception("Forgot to specify previous when atoms is None!")
        atom_str = atom_str.replace("$$NAME$$", previous_name)
    script = script.replace("$$ATOMS$$", atom_str)

    while "$$NAME$$" in script:
        script = script.replace("$$NAME$$", run_name)
    if ecutrho is None:
        ecutrho = ""
    while "$$ECUTRHO$$" in script:
        script = script.replace("$$ECUTRHO$$", str(ecutrho))
    while "$$ECUT$$" in script:
        script = script.replace("$$ECUT$$", str(ecut))
    while "$$PSEUDOPOTENTIALS$$" in script:
        script = script.replace("$$PSEUDOPOTENTIALS$$", pseudopotentials)
    if previous is not None:
        script = script.replace("$$PREVIOUS$$", previous)
    else:
        script = script.replace("$$PREVIOUS$$", "")
    script = script.replace("$$DUMPS$$", dumps)

    if route is not None:
        script += "\n# --------------- Outputs ----------------\n\n"
        script += route.strip() + "\n\n"

    fptr = open("%s.in" % run_name, 'w')
    fptr.write(script)
    fptr.close()

    # Run the simulation
    if queue is None:
        process_handle = subprocess.Popen("%s/jdftx -i %s.in -o %s.out" %
                                          (path_jdftx, run_name, run_name),
                                          shell=True)
    elif queue == 'debug':
        print 'Would run', run_name
    else:
        job_to_submit = "source ~/.zshrc\nmpirun -n %d jdftx -c %d -i %s.in -o %s.out" % (
            procs, threads, run_name, run_name)

        jobs.submit_job(run_name,
                        job_to_submit,
                        procs=procs,
                        queue=queue,
                        mem=mem,
                        priority=priority,
                        walltime=walltime,
                        xhosts=xhost,
                        redundancy=redundancy,
                        unique_name=True,
                        slurm_allocation=slurm_allocation)
        time.sleep(0.5)
    # Copy run script
    fname = sys.argv[0]
    if '/' in fname:
        fname = fname.split('/')[-1]
    try:
        shutil.copyfile('../../%s' % fname, fname)
    except IOError:
        # Submitted a job oddly enough that sys.argv[0]
        # is not the original python file name, so don't do this
        pass

    # Return to the appropriate directory
    os.chdir('../..')

    if queue is None:
        return jobs.Job(run_name, process_handle=process_handle)
    else:
        return jobs.Job(run_name)