def load_run_input(): from pylada.vasp import read_input # options, args = load_options() rin = "run_input.py" run_input = read_input("input_generic.py") # run_input.update(read_input(options.run_input_name)) run_input.update(read_input(rin)) return run_input
def save_job(path, inputpath="input.py", **kwargs): """ Jobs to explore possible ground-states. :Parameters: path Path where the job-folder will be saved. Calculations will be performed in the parent directory of this file. Calculations will be performed in same directory as this file. inputpath Path to an input file. Defaults to input.py. kwargs Any keyword/value pair to take precedence over anything in the input file. Creates a high-throughput job-folder to compute the non-magnetic ground-state of a host-material. The new job-folder is loaded into memory automatically. No need to call explore. It is save to the path provided on input. """ import re from IPython.core.interactiveshell import InteractiveShell from copy import deepcopy from pylada.vasp import read_input from pylada.jobfolder import JobFolder from pylada import interactive from pylada.misc import setBugLev setBugLev(0) # set global debug level from pylada.misc import bugLev # reads input. input = read_input(inputpath) input.update(kwargs) # Job dictionary. jobfolder = JobFolder() # loop over material-lattice pairs. for (material, lattice) in input.matLatPairs: structure = deepcopy(lattice) # job folder for this lattice. lat_jobfolder = jobfolder / material job = lat_jobfolder / lattice.name / "basin_hoping" job.functional = input.calc job.params["structure"] = structure job.params["ispin"] = 1 job.params["vasp"] = input.vasp job.params["programs"] = input.programs job.params["func_param"] = input.func_param # saves some stuff for future reference. job.material = material job.lattice = lattice #print ' test/hi/test: job: ', job #print ' test/hi/test: === job.functional ===\n%s\n=== end functional === ' % (job.functional,) interactive.jobfolder = jobfolder InteractiveShell.instance().magic("savefolders " + path)
def create(input='input.py'): """ Load ga into ipython. """ from os.path import exists from pickle import dump from pylada.vasp import read_input from pylada.ga.xgsgo.functional import Functional from pylada.jobfolder import JobFolder input = read_input(input) root = JobFolder() for trial in xrange(input.trials): folder = root / "results" / str(trial) folder.functional = Functional( functional = input.vasp, species = input.species, natoms = input.natoms, rate = input.rate, popsize = input.popsize, cns_rate = input.cns_rate, mix_atoms_rate = input.mix_atoms_rate, mix_poscar_rate = input.mix_poscar_rate, mutation_rate = input.mutation_rate ) return root
import pylada pylada.pylada_with_mpi = False from pylada.vasp import read_input input = read_input("input.py") input.structure.name = "has a name" input.vasp(input.structure, outdir="results", comm={'n': 2, 'ppn': 1})
def calcGW( path=None, inputpath='inputGW.py', **kwargs): """ Runs GW calcs on all subfolders. :Parameters: path : str or None Path where the modified job-folder will be saved. Calculations will be performed in the parent directory of this file. If None, will use the current job-folder path. inputpath : str or None Path to an input file. kwargs Any keyword/value pair to take precedence over anything in the input file. """ from tempfile import NamedTemporaryFile from os.path import dirname, normpath, relpath, join from IPython.core.interactiveshell import InteractiveShell from pylada.vasp import read_input from pylada.jobfolder import JobFolder from pylada import interactive import pickle, random from pylada.misc import setBugLev setBugLev(0) # set global debug level from pylada.misc import bugLev with open(path) as fin: jobfolder = pickle.load( fin) basedir = dirname( path) jobfolder_path = join( basedir, jobfolder.name) # Loads job-folder and path as requested. if jobfolder is None: print "No current job-folder." return if jobfolder_path is None: print "No path for current job-folder." return input = read_input(inputpath) print ' test/hi/test gw: inputpath: ', inputpath print ' test/hi/test gw: input.vasp.relaxation: ', input.vasp.relaxation # will loop over all folders, looking for all successfull calculations. nb_new_folders = 0 for name, pjob in jobfolder.iteritems(): if bugLev >= 1: print "test/hi/test gw: name: %s pjob: %s" % (name, pjob,) # avoid tagged folders. if pjob.is_tagged: continue basename = normpath("/" + name + "/../") if bugLev >= 1: print "test/hi/test gw: basename: %s" % (basename,) # check for success and avoid failures. extractPath = join(basedir, name) extract = pjob.functional.Extract( extractPath) if bugLev >= 1: print "test/hi/test gw: extractPath: %s" % (extractPath,) print "test/hi/test gw: extract.success: %s" % (extract.success,) print "test/hi/test gw: extract: %s" % (extract,) print "test/hi/test gw: dir(extract): %s" % (dir(extract),) if not extract.success: continue if bugLev >= 1: print 'test/hi/test gw ========== A' print "test/hi/test gw: nonmag structure: %s" % (pjob.structure,) print 'test/hi/test gw ========== B' print "test/hi/test gw: extract.structure: %s" % (extract.structure,) print 'test/hi/test gw ========== C' print "test/hi/test gw: extract.species: %s" % (extract.species,) print "test/hi/test gw: extract functional species: %s" \ % (extract.functional.species,) print 'test/hi/test gw ========== D' print "test/hi/test gw: dir(pjob): %s" % (dir(pjob),) print 'test/hi/test gw ========== E' # loads lattice and material from previous job. material = pjob.material lattice = pjob.lattice if bugLev >= 1: print "test/hi/test gw: material: %s" % (material,) print "test/hi/test gw: lattice: %s" % (lattice,) jobname = pjob.name + '/gwcalc' structure = extract.structure.copy() structure.name = "{0} in {1}, GW.".format(material, lattice.name) if bugLev >= 1: print "test/hi/test gw: jobname: %s" % (jobname,) print "test/hi/test gw: structure.name: %s" % (structure.name,) job = jobfolder / jobname if bugLev >= 1: print "test/hi/test gw: job: %s" % (job,) job.functional = input.vasp job.params["structure"] = structure.copy() job.params["magmom"] = True job.params["ispin"] = 2 # saves some stuff for future reference. job.material = material job.lattice = lattice print "test/hi/test gw: created ferro jobname: %s" % (jobname,) nb_new_folders += 1 # now saves new job folder print "Created {0} new folders.".format(nb_new_folders) if nb_new_folders == 0: return interactive.jobfolder = jobfolder.root InteractiveShell.instance().magic("savefolders " + path)
def nonmagnetic_wave(path, inputpath="input.py", **kwargs): """ Jobs to explore possible ground-states. :Parameters: path Path where the job-folder will be saved. Calculations will be performed in the parent directory of this file. Calculations will be performed in same directory as this file. inputpath Path to an input file. Defaults to input.py. kwargs Any keyword/value pair to take precedence over anything in the input file. Creates a high-throughput job-folder to compute the non-magnetic ground-state of a host-material. The new job-folder is loaded into memory automatically. No need to call explore. It is save to the path provided on input. """ import re from IPython.core.interactiveshell import InteractiveShell from copy import deepcopy from pylada.vasp import read_input from pylada.jobfolder import JobFolder from pylada import interactive from pylada.misc import setBugLev setBugLev(0) # set global debug level from pylada.misc import bugLev # reads input. input = read_input(inputpath) print ' test/hi/test nonmag: inputpath: ', inputpath print ' test/hi/test nonmag: input.vasp.relaxation: ', input.vasp.relaxation input.update(kwargs) # """ Materials to compute. """ # materials = [ "Al2MgO4"] # # """ Number of random anti-ferro trials. """ # nbantiferro = 8 # nbrandom = 3 # do_ferro = False # do_antiferro = False # # from pylada.crystal import A2BX4 # lattices = [A2BX4.b5(), A2BX4.b21()] # # mlen = len( materials) # llen = len( lattices) # matLatPairs = (mlen * llen) * [None] # print " test/hi/test nonmag: mlen: ", mlen # print " test/hi/test nonmag: llen: ", llen # print " test/hi/test nonmag: pairs len: ", len(matLatPairs) # # kk = 0 # for mat in materials: # print " test/hi/test nonmag: mat: ", mat # for lat in lattices: # print " test/hi/test nonmag: lat: ", lat # matLatPairs[kk] = (mat, lat,) # kk += 1 # # print "test/hi/test nonmag: mats len: %d lats len: %d matLatPairs len: %d" \ # % (mlen, llen, len( matLatPairs),) # Job dictionary. jobfolder = JobFolder() # loop over material-lattice pairs. for (material,lattice) in input.matLatPairs: if bugLev >= 1: print ' test/hi/test nonmag: start material: ', material print ' test/hi/test nonmag: start lattice: ', lattice print '' if bugLev >= 5: print ' test/hi/test nonmag: ========== species ==========' skeys = input.vasp.species.keys() skeys.sort() for skey in skeys: print ' test/hi/test nonmag: species[%s]: %s' \ % (skey, input.vasp.species[skey], ) print '' if getattr( input, 'useInputCif', None) == True: structure = deepcopy(lattice) else: # Check material regex = "([A-Z][a-z]?)2([A-Z][a-z]?)([A-Z][a-z]?)4" match = re.match( regex, material) if match == None: raise RuntimeError("Incorrect material: \"%s\"" % (material,)) # Checks species are known to vasp functional for i in range(1, 4): assert match.group(i) in input.vasp.species,\ RuntimeError("No pseudo-potential defined for {0}.".format( match.group(i))) # actually creates dictionary. species_dict = {"A": match.group(1), "B": match.group(2), "X": match.group(3)} #print ' test/hi/test nonmag: species_dict: ', species_dict # Check lattice name if len(getattr(lattice, 'name', '').strip()) == 0: raise ValueError("Lattice has no name.") # creates a structure. structure = deepcopy(lattice) # changes atomic species, from ABX to real element names. # from: Atom(0.5, 0.5, 0.5, 'A') # to: Atom(0.5, 0.5, 0.5, 'Al') for atom in structure: atom.type = species_dict[atom.type] # assigns it a name. structure.name = "{0} in {1}, spin-unpolarized.".format( material, lattice.name) # gets its scale. structure.scale = input.scale(structure) # job folder for this lattice. lat_jobfolder = jobfolder / material job = lat_jobfolder / lattice.name / "non-magnetic" job.functional = input.vasp job.params["structure"] = structure job.params["ispin"] = 1 # saves some stuff for future reference. job.material = material job.lattice = lattice #print ' test/hi/test nonmag: job: ', job #print ' test/hi/test nonmag: === job.functional ===\n%s\n=== end functional === ' % (job.functional,) interactive.jobfolder = jobfolder InteractiveShell.instance().magic("savefolders " + path)
def magnetic_wave( path=None, inputpath='input.py', **kwargs): """ Creates magnetic wave for current job-folder. :Parameters: path : str or None Path where the modified job-folder will be saved. Calculations will be performed in the parent directory of this file. If None, will use the current job-folder path. inputpath : str or None Path to an input file. If not present, then no input file is read and all parameters are taken from the non-magnetic wave. kwargs Any keyword/value pair to take precedence over anything in the input file. Creates magnetic wave from pre-existing non-magnetic wave. If no input file is given on input, then all parameters are obtained from the corresponding non-magnetic wave. The new job-folder is loaded into memory automatically. No need to call explore. It is save to the path provided on input (or to the current job-folder path ifnot provided). It will contain magnetic and non-magnetic calculations both. Pre-existing magnetic calculations will *not* be overwritten. However, additional anti-ferro configurations can be calculated by giving a large enough ``nbantiferro`` on input. """ from tempfile import NamedTemporaryFile from os.path import dirname, normpath, relpath, join from IPython.core.interactiveshell import InteractiveShell from pylada.vasp import read_input from pylada.jobfolder import JobFolder from pylada import interactive import pickle, random from pylada.misc import setBugLev setBugLev(0) # set global debug level from pylada.misc import bugLev with open(path) as fin: jobfolder = pickle.load( fin) basedir = dirname( path) jobfolder_path = join( basedir, jobfolder.name) # Loads job-folder and path as requested. if jobfolder is None: print "No current job-folder." return if jobfolder_path is None: print "No path for current job-folder." return input = read_input(inputpath) print ' test/hi/test mag: inputpath: ', inputpath print ' test/hi/test mag: input.vasp.relaxation: ', input.vasp.relaxation # will loop over all folders, looking for *successfull* *non-magnetic* calculations. # Only magnetic folders which do NOT exist are added at that point. nonmagname = "non-magnetic" nb_new_folders = 0 for name, nonmagjob in jobfolder.iteritems(): if bugLev >= 1: print "test/hi/test mag: name: %s nonmagjob: %s" % (name, nonmagjob,) # avoid tagged folders. if nonmagjob.is_tagged: continue # avoid other folders (eg magnetic folders). basename = normpath("/" + name + "/../") if bugLev >= 1: print "test/hi/test mag: basename: %s" % (basename,) if relpath(name, basename[1:]) != nonmagname: continue # check for success and avoid failures. extractPath = join(basedir, name) # xxx use contcar extract = nonmagjob.functional.Extract( extractPath) if bugLev >= 1: print "test/hi/test mag: extractPath: %s" % (extractPath,) print "test/hi/test mag: extract.success: %s" % (extract.success,) print "test/hi/test mag: extract: %s" % (extract,) print "test/hi/test mag: dir(extract): %s" % (dir(extract),) print "test/hi/test mag: extract.functional: %s" % (extract.functional,) if not extract.success: continue if bugLev >= 1: print 'test/hi/test mag ========== A' print "test/hi/test mag: nonmag structure: %s" % (nonmagjob.structure,) print 'test/hi/test mag ========== B' print "test/hi/test mag: extract.structure: %s" % (extract.structure,) print 'test/hi/test mag ========== C' print "test/hi/test mag: extract.species: %s" % (extract.species,) print 'test/hi/test mag ========== D' if not is_magnetic_system(extract.structure, extract.functional.species): continue # loads lattice and material from non-magnetic job. material = nonmagjob.material lattice = nonmagjob.lattice if bugLev >= 1: print "test/hi/test mag: material: %s" % (material,) print "test/hi/test mag: lattice: %s" % (lattice,) # figures out whether we have both high and low spins. if bugLev >= 1: print "test/hi/test mag: extract structure: %s" % (extract.structure,) print "test/hi/test mag: extract species: %s" \ % (extract.functional.species,) if has_high_and_low(extract.structure, extract.functional.species): hnl = [(min, "ls-"), (max, "hs-")] else: hnl = [(min, "")] # now loops over moments. for func, prefix in hnl: if bugLev >= 1: print "test/hi/test mag: func: %s prefix: %s" % (func, prefix,) # Either func=min,prefix="ls-", or func=max,prefix="hs-" # Now tries and creates high-spin ferro folders # if it does not already exist. jobname = normpath("{0}/{1}ferro".format(basename, prefix)) structure, magmom = ferro( extract.structure, extract.functional.species, func) if bugLev >= 1: print "test/hi/test mag: structure: %s" % (structure,) print "test/hi/test mag: jobfolder: %s" % (jobfolder,) print "test/hi/test mag: jobname: %s" % (jobname,) print "test/hi/test mag: magmom: %s" % (magmom,) print "test/hi/test mag: input.do_ferro: %s" % (input.do_ferro,) if magmom and jobname not in jobfolder and input.do_ferro: structure.name = "{0} in {1}, {2}ferro."\ .format(material, lattice.name, prefix) job = jobfolder / jobname if bugLev >= 1: print "test/hi/test mag: structure.name: %s" % (structure.name,) print "test/hi/test mag: job: %s" % (job,) job.functional = input.vasp job.params["structure"] = structure.copy() job.params["magmom"] = True job.params["ispin"] = 2 # saves some stuff for future reference. job.material = material job.lattice = lattice print "test/hi/test mag: created ferro jobname: %s" % (jobname,) nb_new_folders += 1 # Now tries and creates anti-ferro-lattices folders # if it does not already exist. structure, magmom = species_antiferro( extract.structure, extract.functional.species, func) jobname = normpath("{0}/{1}anti-ferro-0".format(basename, prefix)) if magmom and jobname not in jobfolder and input.do_antiferro: structure.name = "{0} in {1}, {2}specie-anti-ferro."\ .format(material, lattice.name, prefix) job = jobfolder / jobname job.functional = input.vasp job.params["structure"] = structure.copy() job.params["magmom"] = True job.params["ispin"] = 2 # saves some stuff for future reference. job.material = material job.lattice = lattice print "test/hi/test mag: created anti ferro jobname: %s" % (jobname,) nb_new_folders += 1 # Random anti-ferro, or all possible anti-ferro. magIxs = [] # indices of magnetic atoms for ii in range( len( extract.structure)): atom = extract.structure[ii] if len(deduce_moment(atom, extract.functional.species)) > 1: magIxs.append( ii) numMagAtom = len( magIxs) # Total num tests = 2**numMagAtom, but each one is counted # twice, since ddd == uuu, and ddu == uud, etc., # where d = spin down, u = spin up. # So the num unique tests = 2**numMagAtom / 2 numUnique = 2 ** (numMagAtom - 1) # If the user asked for at least half the total num unique tests, # we may as well do them all print "test/hi/test mag: numMagAtom: %d numUnique: %d input.nbantiferro: %d" \ % ( numMagAtom, numUnique, input.nbantiferro,) if input.nbantiferro >= numUnique / 2: # Do all possible combinations print 'test/hi/test mag: Do all possible antiferro combinations' for itest in range( numUnique): jobname = runAntiFerroTest( bugLev, jobfolder, material, lattice, inputpath, input, magIxs, extract, basename, func, prefix, itest, itest) print "test/hi/test mag: created all anti ferro jobname: %s" \ % (jobname,) nb_new_folders += 1 else: # Only run a few random combinations print 'test/hi/test mag: Do a random selection of antiferro combinations' doneMap = {} ix = 0 while True: itest = random.randint( 0, numUnique - 1) if itest not in doneMap: doneMap[itest] = True jobname = runAntiFerroTest( bugLev, jobfolder, material, lattice, inputpath, input, magIxs, extract, basename, func, prefix, ix, itest) print "test/hi/test mag: created random anti ferro jobname: %s" \ % (jobname,) nb_new_folders += 1 ix += 1 if ix >= input.nbantiferro: break # now saves new job folder print "Created {0} new folders.".format(nb_new_folders) if nb_new_folders == 0: return interactive.jobfolder = jobfolder.root InteractiveShell.instance().magic("savefolders " + path)
def save_job(path, inputpath="input.py", **kwargs): """ Jobs to explore possible ground-states. :Parameters: path Path where the job-folder will be saved. Calculations will be performed in the parent directory of this file. Calculations will be performed in same directory as this file. inputpath Path to an input file. Defaults to input.py. kwargs Any keyword/value pair to take precedence over anything in the input file. Creates a high-throughput job-folder to compute the non-magnetic ground-state of a host-material. The new job-folder is loaded into memory automatically. No need to call explore. It is save to the path provided on input. """ import re from IPython.core.interactiveshell import InteractiveShell from copy import deepcopy from pylada.vasp import read_input from pylada.jobfolder import JobFolder from pylada import interactive from pylada.misc import setBugLev setBugLev(0) # set global debug level from pylada.misc import bugLev # reads input. input = read_input(inputpath) input.update(kwargs) # Job dictionary. jobfolder = JobFolder() # loop over material-lattice pairs. for (material,lattice) in input.matLatPairs: structure = deepcopy(lattice) # job folder for this lattice. lat_jobfolder = jobfolder / material job = lat_jobfolder / lattice.name / "basin_hoping" job.functional = input.calc job.params["structure"] = structure job.params["ispin"] = 1 job.params["vasp"] = input.vasp job.params["programs"] = input.programs job.params["func_param"] = input.func_param # saves some stuff for future reference. job.material = material job.lattice = lattice #print ' test/hi/test: job: ', job #print ' test/hi/test: === job.functional ===\n%s\n=== end functional === ' % (job.functional,) interactive.jobfolder = jobfolder InteractiveShell.instance().magic("savefolders " + path)
def pointdefect_wave(path=None, inputpath=None, **kwargs): """ Creates point-defect wave using ground-state job-dictionary. :Parameters: path : str or None Path where the modified job-dictionary will be saved. Calculations will be performed in the parent directory of this file. If None, will use the current job-dictionary path. inputpath : str or None Path to an input file. If not present, then no input file is read and all parameters are taken from the non-magnetic wave. kwargs Any keyword/value pair to take precedence over anything in the input file. Creates a point-defect wave from the materials computed in the magnetic and non-magnetic waves. Usage is fairly simple. If the pickle for the magnetic/non-magnetic wave is called ``magnetic_wave``, then one need only open it and call the ``pointdefect_wave``. >>> explore all magnetic_wave >>> import test >>> test.magnetic_wave() >>> launch scattered The above will add point-defect calculations for all meterials and lattices of the ``magnetic_wave`` job-dictionary and save it (to the same path unless an argument is provided to ``magnetic_wave``). Note that changing the location of the current job-dictionary has no effect. It would be possible but sounds too error prone: >>> explore all magnetic_wave >>> goto /Fe2AlO4 # has no effect on what point-defects are added. >>> goto /Al2FeO4 # has no effect on what point-defects are added. >>> import test >>> # creates point-defects for both Fe2AlO4 and Al2FeO4: location does not matter. >>> test.magnetic_wave() >>> launch scattered Point-defects calculations are added to a material if and only if all existing magnetic/non-magnetic jobs for that material have completed successfully. Furthermore, only untagged materials are accepted. Hence, to disable Fe2AlO4 lattices from having point-defects added to it, one can simply tag it: >>> explore all magnetic_wave >>> jobparams["/Fe2AlO4"] = 'off' >>> import test >>> test.magnetic_wave() >>> launch scattered Similarly to make sure point-defect calculations are *not* created for the b5 lattice of the Fe2AlO4 material, one could tag it as follows: >>> explore all magnetic_wave >>> current_jobfolder["/Fe2AlO4/b5"].tag() >>> import test >>> test.magnetic_wave() >>> launch scattered """ from tempfile import NamedTemporaryFile from os.path import dirname, normpath, relpath, join from IPython.ipapi import get as get_ipy from numpy import array, sum, abs from pylada.jobs import JobFolder from pylada.vasp import read_input from pylada.opt import Input from pylada.crystal import defects as ptd # Loads job-folder and path as requested. ip = get_ipy() if "current_jobfolder" not in ip.user_ns: print "No current job-dictionary." return jobfolder = ip.user_ns["current_jobfolder"].root if path is None: if "current_jobfolder_path" not in ip.user_ns: print "No known path for current dictionary and no path specified on input." return path = ip.user_ns["current_jobfolder_path"] basedir = dirname(path) # create input dictionary. First reads non-magnetic input, then magnetic # input, then kwargs. Order of precedence is exact opposite. input = Input() if hasattr(jobfolder, "nonmaginput"): with NamedTemporaryFile() as file: file.write(jobfolder.nonmaginput) file.flush() input.update(read_input(file.name)) if hasattr(jobfolder, "maginput"): with NamedTemporaryFile() as file: file.write(jobfolder.nonmaginput) file.flush() input.update(read_input(file.name)) if inputpath is not None: input.update(read_input(inputpath)) with open(inputpath, "r") as file: jobfolder.maginput = file.read() input.update(kwargs) # saves inputfile to jobfolderioanry if needed. if inputpath is not None: input.update(read_input(inputpath)) with open(inputpath, "r") as file: jobfolder.pointdefectinput = file.read() # saves current script tof file. with open(__file__, "r") as file: jobfolder.pointdefectscript = file.read() if hasattr(input, 'coord_tolerance'): coord_tolerance = input.coord_tolerance nb_new_jobs = 0 # loops over completed structural jobs. for name in magnetic_groundstates(): # gets the ground-states job-dictionary. groundstate = jobfolder[name] # checks that the lattice and material are not tagged. if groundstate[".."].is_tagged: continue if groundstate["../.."].is_tagged: continue # extracts the structure from it. superstructure, lattice = create_superstructure(groundstate, input) # extracts material. material = groundstate.material print 'Working on ', groundstate.name, groundstate.name.split('/')[1] # extracts description of species. species = groundstate.functional.vasp.species # loop over substitutees. for structure, defect, B in ptd.iterdefects(superstructure, lattice, input.point_defects, tolerance=coord_tolerance): # loop over oxidations states. for nb_extrae, oxname in charged_states(input.vasp.species, material, defect.type, B): # creates list of moments. new_moments = deduce_moment(defect.type, species) if len(new_moments) > 1: moments = [ (min(new_moments), "/ls"), (max(new_moments), "/hs") ] else: moments = [ (max(new_moments), "") ] # loop over moments. for moment, suffix in moments: name = "PointDefects/{1}/{2}{0}".format(suffix, structure.name, oxname) # checks if job already exists. Does not change job if it exists! if name in groundstate[".."]: continue # creates new job. jobfolder = groundstate["../"] / name jobfolder.functional = input.relaxer jobfolder.jobparams = groundstate.jobparams.copy() jobfolder.jobparams["structure"] = structure.deepcopy() jobfolder.jobparams["nelect"] = nb_extrae jobfolder.jobparams["relaxation"] = "ionic" jobfolder.jobparams["ispin"] = 2 jobfolder.jobparams["set_symmetries"] = "off" jobfolder.lattice = lattice jobfolder.material = material jobfolder.defect = defect # adds, modifies, or remove moment depending on defect type. if hasattr(superstructure, "magmom") or abs(moment) > 1e-12: jstruct = jobfolder.jobparams["structure"] # construct initial magmom if hasattr(superstructure, "magmom"): jstruct.magmom = [u for u in superstructure.magmom] else: jstruct.magmom = [0 for u in superstructure.atoms] # now modifies according to structure. if B is None or B.lower() == 'none': # interstitial: jstruct.magmom.append(moment) elif defect.type is None or defect.type.lower() == 'none': vacancy_moment(input.vasp.species, jstruct, defect, B, nb_extrae) else: jstruct.magmom[defect.index] = moment # only keep moment if there are moments. if sum(abs(jstruct.magmom)) < 1e-12 * float(len(jstruct.atoms)): del jstruct.magmom nb_new_jobs += 1 # now saves new job folder print "Created {0} new jobs.".format(nb_new_jobs) if nb_new_jobs == 0: return ip.user_ns["current_jobfolder"] = jobfolder.root ip.magic("savejobs " + path)