def iter(self, outdir=None, sleep=None, overwrite=False, comm=None): from copy import deepcopy from os.path import join from pylada.process.program import ProgramProcess from pylada.misc import RelativePath self = deepcopy(self) outdir = RelativePath(outdir).path if sleep is not None: self.sleep = sleep order = self.order if hasattr(self.order, '__iter__') else [self.order] for o in order: stdout = join(outdir, 'stdout{0}'.format(o)) stderr = join(outdir, 'stderr{0}'.format(o)) if overwrite == False: extract = ExtractSingle(stdout) if extract.success: yield extract continue cmdline = ['--order', str(o), '--sleep', str(self.sleep)] if self.fail == 'midway': cmdline.append('--fail-mid-call') elif self.fail == 'end': cmdline.append('--fail-at-end') yield ProgramProcess(self.program, cmdline=cmdline, outdir=outdir, stdout=stdout, stderr=stderr, dompi=True, comm=comm)
def __call__(self, outdir=None, sleep=None, overwrite=False, comm=None): from pylada.misc import RelativePath outdir = RelativePath(outdir).path for program in self.iter(outdir, sleep, overwrite): if getattr(program, 'success', False) == False: program.start(comm) program.wait() return self.Extract(outdir)
def functional(vasp, structure, programs, restart=False, outdir=None, value=False, **kwargs): """ A simulated annealing functional """ from copy import deepcopy from pickle import dump from random import random from pylada.misc import Changedir from os.path import join from pylada.crystal import vasp_ordered from pylada.misc import RelativePath structure = deepcopy(structure) vasp = deepcopy(vasp) outdir = getcwd() if outdir is None else RelativePath(outdir).path #structure = vasp_ordered(structure) if programs is None: programs = [{}] # TODO: restart step_todo = 0 output = None for step, program in enumerate(programs[step_todo:]): params = kwargs.copy() params.update(program) if 'add_param' in params.keys(): for key in params['add_param'].keys(): if key not in vasp.__dict__['_input'].keys(): print key vasp.add_keyword(key, params['add_param'][key]) output = vasp\ (\ structure, outdir = join(outdir, str(step+step_todo)), restart = output, **params ) output = vasp.Extract(join(outdir, str(step + step_todo))) structure = output.structure assert output.success, RuntimeError("VASP run did not succeed.") # performs final calculation print programs[0].keys() output = vasp\ (\ structure, \ outdir = outdir,\ relaxation = "static",\ restart = output, \ **kwargs\ ) return Extract(outdir)
def __call__(self, structure, outdir=None, names=None, functionals=None, previous=None, **kwargs): from Generate_Surface import get_bottom, get_SD_along_vector from Helpers import pyl_to_pmg if not functionals: functionals = self.functionals outdir = os.getcwd() if outdir is None else RelativePath(outdir).path sp_functionals = [ CustomFunctional(functional.base, functional.modifications + [no_relax], functional.type) for functional in functionals[self.to_run:] ] structure_frozen_bot = structure.copy() pmg_s = pyl_to_pmg(structure) sd_bottom = get_SD_along_vector(pmg_s, 2, get_bottom(pmg_s, region='bot')) for (atom, sd) in zip(structure_frozen_bot, sd_bottom): if sd[0]: atom.freeze = 'xyz' structure_frozen_top = structure.copy() sd_top = get_SD_along_vector(pmg_s, 2, get_bottom(pmg_s, region='top')) for (atom, sd) in zip(structure_frozen_top, sd_top): if sd[0]: atom.freeze = 'xyz' # Clevage Energy (clevage, previous) = self.call_with_output(structure, outdir=outdir, names=self.names[-3:], functionals=sp_functionals, previous=previous) # Frozen Bottom (bottom, clevage) = self.call_with_output(structure_frozen_bot, outdir=os.path.join( outdir, 'bottom'), names=names, functionals=functionals, previous=clevage) # Frozen Top (bottom, clevage) = self.call_with_output(structure_frozen_top, outdir=os.path.join(outdir, 'top'), names=names, functionals=functionals, previous=clevage) return clevage
def __init__(self, outdir, order=None): from glob import iglob from os.path import join, basename from pylada.misc import RelativePath super(ExtractMany, self).__init__() self.directory = RelativePath(outdir).path checkdir = order is None if checkdir: order = [] for file in iglob(join(self.directory, 'stdout*')): o = int(basename(file)[6:]) extract = ExtractSingle(file) if not extract.success: continue if extract.order == o: order.append(o) self.order = [] self.sleep = [] self.pi = [] self.error = [] self.system = [] self.version = [] self.machine = [] self.nodename = [] self.release = [] self.comm = [] self.success = False error = False try: for o in order: extract = ExtractSingle( join(self.directory, 'stdout') + str(o)) if not extract.success: error = True continue if extract.order != o: error = True continue self.order.append(o) self.pi.append(extract.pi) self.error.append(extract.error) self.system.append(extract.system) self.version.append(extract.version) self.nodename.append(extract.nodename) self.machine.append(extract.machine) self.release.append(extract.release) self.comm.append(extract.comm) except: self.success = False else: self.success = not error
def __call__(self, structure, outdir=None, **kwargs ): from copy import deepcopy from os import getcwd from os.path import join from pylada.misc import RelativePath from pylada.error import ExternalRunFailed from pylada.vasp.extract import Extract from pylada.vasp import Vasp from pylada.vasp.relax import Relax # make this function stateless. structure_ = structure.copy() outdir = getcwd() if outdir is None else RelativePath(outdir).path ############ Calc 1 ############### name = self.names[0] ## functional for Calc 1 relax = Relax(copy=deepcopy(self.vasp)) relax.relaxation = "volume ionic cellshape" relax.maxiter = 10 relax.keep_steps = True relax.first_trial = { "kpoints": "\n0\nAuto\n10", "encut": 0.9 } ## end of the functional params = deepcopy(kwargs) fulldir = join(outdir, name) ## if this calculation has not been done run it output = relax(structure_, outdir=fulldir, **params) if not output.success: raise ExternalRunFailed("VASP calculation did not succeed.") ############ Calc 2 ############### name = self.names[1] ## functional for Calc 2 wfn = Vasp(copy=deepcopy(self.vasp)) wfn.isym = 1 wfn.ismear = -5 wfn.nbands=24*len(structure_) wfn.kpoints="\n0\nGamma\n4 4 4\n0. 0. 0.\n" ## end of the functional params = deepcopy(kwargs) fulldir = join(outdir, name) ## if this calculation has not been done, run it output = wfn(structure_, outdir=fulldir, restart=output, **params) if not output.success: raise ExternalRunFailed("VASP calculation did not succeed.") return self.Extract(fulldir)
def __init__(self, outdir): from os.path import exists, isfile, isdir, join from re import search from pylada.misc import RelativePath super(ExtractSingle, self).__init__() outdir = RelativePath(outdir).path if isdir(outdir): outdir = join(outdir, 'stdout') self.directory = outdir self.success = False if not exists(outdir): return if not isfile(outdir): return try: with open(outdir, 'r') as file: line = next(file) regex = search( "pi to order (\d+) is approximately (\S+), " "Error is (\S+) " "\s*-- slept (\S+) seconds at each iteration -- " "\s*mpi world size is (\d+)", line) if regex is None: return self.order = int(regex.group(1)) self.pi = float(regex.group(2)) self.error = float(regex.group(3)) self.sleep = float(regex.group(4)) self.comm = {'n': int(regex.group(5))} line = next(file) if line[:line.find(':')].rstrip().lstrip() != 'sysname': self.success = False return self.system = line[line.find(':') + 1:].rstrip().lstrip() line = next(file) self.nodename = line[line.find(':') + 1:].rstrip().lstrip() line = next(file) self.release = line[line.find(':') + 1:].rstrip().lstrip() line = next(file) self.compilation = line[line.find(':') + 1:].rstrip().lstrip() line = next(file) self.version = line[line.find(':') + 1:].rstrip().lstrip() line = next(file) self.machine = line[line.find(':') + 1:].rstrip().lstrip() except: self.success = False else: self.success = True
def iter(self, outdir=None, sleep=None, overwrite=False, comm=None): from copy import deepcopy from os.path import join from pylada.process.program import ProgramProcess from pylada.misc import RelativePath self = deepcopy(self) outdir = RelativePath(outdir).path if sleep is not None: self.sleep = sleep stdout = join(outdir, 'stdout') stderr = join(outdir, 'stderr') if overwrite == False: extract = ExtractSingle(stdout) if extract.success: yield extract return yield ProgramProcess( self.program, cmdline=['--order', str(self.order), '--sleep', str(self.sleep)], outdir=outdir, stdout=stdout, stderr=stderr, dompi=False, comm=comm)
short1.wait() print 'SECOND SHORT PROCESS FINISHED' assert not long.poll() print 'TESTED PROCESS OVERLAP' long.wait() print 'LONG PROCESS FINISHED' assert lfunc.Extract('long').success assert sfunc.Extract('short0').success assert sfunc.Extract('short1').success print 'END' if __name__ == '__main__': # ppn should be the number of processors per node # the job should be allocated with 2*ppn processors ppn = 32 # path is the path to the Pylada source code path = '~/usr/src/Pylada/master/' from pylada.misc import RelativePath from os import chdir chdir('/home/e05/e05/mdavezac/bull') # crappy Cray path = RelativePath(path).path import sys sys.path.append(path + '/process/tests') print sys.path test( nbprocs=2*ppn, ppn=ppn, executable=path + '/build/process/tests/pifunc' )
def run_calculation(self, name, workflow: CustomFunctional, structure, outdir, previous, **kwargs): ''' The important function run when __call__ is invoked :param name: name (subfolder) of current run :param workflow: The workflow to be run :param structure: Structure that will be relaxed :param outdir: Directory for output :param previous: Previous directory (for initialization) :param kwargs: :return: ''' vasp = workflow.base(copy=deepcopy(self.vasp)) structure_ = structure.copy() outdir = os.getcwd() if outdir is None else RelativePath(outdir).path if 'encut' in self.kwargs: vasp.encut = self.kwargs['encut'] num_kpoints = 99999 if 'kpoints' in self.kwargs: density = self.kwargs['kpoints'] if type(density) == int: vasp.kpoints = "Automatic\n0\nAuto\n{}".format( self.kwargs['kpoints']) num_kpoints = math.floor(density / np.linalg.norm(structure.cell[:, 0])+0.5) * \ math.floor(density / np.linalg.norm(structure.cell[:, 1])+0.5) * \ math.floor(density / np.linalg.norm(structure.cell[:, 2])+0.5) elif type(density) == 'str': kpoint_str = vasp.kpoints.split('\n')[3] kpoints = [int(x) for x in kpoint_str.split()] num_kpoints = kpoints[0] * kpoints[1] * kpoints[2] if 'nelect' in self.kwargs: vasp.nelect = self.kwargs['nelect'] for modification in workflow.modifications: vasp = modification(vasp, structure_) print('ISMEAR: |{}|'.format(vasp.ismear)) if num_kpoints < 4: if (vasp.ismear == -4 or vasp.ismear == -5 or vasp.ismear == 'metal' or vasp.ismear == 'tetra'): vasp.ismear = 0 else: print(vasp.ismear) ## if this calculation has not been done run it params = deepcopy(kwargs) fulldir = os.path.join(outdir, name) if workflow.type == 'neb': inital_images = ceil((vasp.images - 1) / 2) + 1 final_images = floor((vasp.images - 1) / 2) + 1 initial = pylada_to_pmg(self.initial_structure) # type: Structure ts = pylada_to_pmg(structure_) # type: Structure final = pylada_to_pmg(self.final_strucutre) # type: Structure # TODO: Don't force interpolation images = initial.interpolate( ts, inital_images, autosort_tol=0.75 )[:-1] # get images up to, but not including, the TS images += ts.interpolate(final, final_images, autosort_tol=0.75) # get images from TS image_i = 0 for image in images: # type: Structure image_dir = os.path.join(fulldir, str(image_i).zfill(2)) os.makedirs(image_dir, exist_ok=True) image.to(fmt='poscar', filename=os.path.join(image_dir, 'POSCAR')) image_i = image_i + 1 output = vasp(structure_, outdir=fulldir, restart=previous, **params) if not output.success: raise ExternalRunFailed("VASP calculation did not succeed.") return output
def __call__(self, structure, outdir=None, vasp=None, **kwargs): from copy import deepcopy from os import getcwd from os.path import join from pylada.misc import RelativePath from pylada.error import ExternalRunFailed from pylada.vasp.extract import Extract, MassExtract from pylada.vasp import Vasp from pylada.vasp.relax import Relax # make this function stateless. structure_ = structure.copy() outdir = getcwd() if outdir is None else RelativePath(outdir).path ############ Calc 1 ############### name = self.names[0] ## functional for Calc 1 relax = Relax(copy=vasp) relax.relaxation = "volume ionic cellshape" relax.maxiter = 10 relax.keep_steps = True relax.first_trial = {"kpoints": "\n0\nAuto\n10", "encut": 0.9} ## end of the functional params = deepcopy(kwargs) fulldir = join(outdir, name) ## if this calculation has not been done run it output = relax(structure_, outdir=fulldir, restart=None, **params) if not output.success: raise ExternalRunFailed("VASP calculation did not succeed.") ############ Calc 2 ############### name = self.names[1] ## functional for Calc 2 final = Vasp(copy=vasp) final.nbands = 24 * len(structure_) final.kpoints = "\n0\nGamma\n2 2 2\n0. 0. 0.\n" final.loptics = True final.relaxation = "static" ## end of the functional params = deepcopy(kwargs) fulldir = join(outdir, name) ## if this calculation has not been done, run it output = final(structure_, outdir=fulldir, restart=output, **params) if not output.success: raise ExternalRunFailed("VASP calculation did not succeed.") ############## GW Loop ######################## for name in self.names[2:]: gw = Vasp(copy=vasp) gw.kpoints = "\n0\nGamma\n2 2 2\n0. 0. 0.\n" gw.nbands = 24 * len(structure_) gw.lcharg = True gw.add_keyword('nelm', 1) gw.add_keyword('algo', 'gw') gw.add_keyword('LMAXFOCKAE', 4) gw.add_keyword('nomega', 64) gw.add_keyword('precfock', 'fast') gw.add_keyword('encutgw', 50) gw.add_keyword('encutlf', 50) gw.add_keyword('lrpa', False) gw.add_keyword('nkred', 2) params = deepcopy(kwargs) fulldir = join(outdir, name) ## if this calculation has not been done, run it output = gw(structure_, outdir=fulldir, restart=output, **params) if not output.success: raise ExternalRunFailed("VASP calculation did not succeed.") ######################### return self.Extract(fulldir)
def functional(vasp, structure, programs, func_param, outdir=None, value=False, **kwargs): """ A simulated annealing functional """ from copy import deepcopy from pickle import dump from random import random from pylada.misc import Changedir from os.path import join from pylada.crystal import vasp_ordered from pylada.misc import RelativePath import numpy as np import move import str_util import deposit import os import shutil structure_tmp = deepcopy(structure) vasp = deepcopy(vasp) outdir = getcwd() if outdir is None else RelativePath(outdir).path #structure = vasp_ordered(structure) if programs is None: programs = [{}] # TODO: restart feature does not work in pylada step_todo = 0 output = None mode = func_param.get("mode", "rls") min_dist_AA = func_param.get("min_dist_AA", 1.0) min_dist_AB = func_param.get("min_dist_AB", 1.0) T = func_param.get("T", 1.) move_type = func_param.get("move_type", "gauss") print 'MOVE type', move_type restart = func_param.get("restart", False) beta = 1./(8.617e-5 * T) #write_parameters(outdir, **kwargs) Nat = len(structure) if restart: for step_todo, program in enumerate(programs): restartdir = join(outdir, str(step_todo)) with Changedir(restartdir) as pwd: last_iter = 0 if os.path.exists('energy.dat'): with open("energy.dat", "r") as file: lines = file.readlines() last_iter = int(lines[-1][:10]) iter_todo = programs[step_todo]["prog_param"]["Nstep"] - last_iter print 'restart info: step_todo, iter_todo', step_todo, iter_todo if iter_todo > 0: if os.path.exists('accept.dat'): with open("accept.dat", "r") as file: lines = file.readlines() last_accept_iter = int(lines[-1][:10]) last_accept_iter_dir = join(outdir, join(join(str(step_todo), "data"), str(last_accept_iter) +'_0' ) ) with Changedir(last_accept_iter_dir) as pwd: structure_tmp = vasp.Extract().structure E = float(vasp.Extract().energy_sigma0) N_min_e = last_accept_iter else: N_min_e = 0 E = 0.0 programs[step_todo]["prog_param"]["Nstep"] = iter_todo with open("tot_iter", "w") as file: file.write( "last_iter %d\n" % last_iter) file.write( "iter_todo %d\n" % iter_todo) file.write( "step %d\n" % step_todo) file.write( "Energy %.3f\n" % E) break else: if os.path.exists('accept.dat'): with open("accept.dat", "r") as file: lines = file.readlines() last_accept_iter = int(lines[-1][:10]) last_accept_iter_dir = join(outdir, join(join(str(step_todo), "data"), str(last_accept_iter) +'_0' ) ) with Changedir(last_accept_iter_dir) as pwd: structure_tmp = vasp.Extract().structure with open("tot_iter", "w") as file: file.write( "success") file.write( "last_iter %d\n" % last_iter) file.write( "iter_todo %d\n" % iter_todo) file.write( "step %d\n" % step_todo) else: step_todo = 0 last_iter = 0 N_min_e = 0 E = 0.0 str_util.relax_structure_v1(structure_tmp, min_dist_AA, min_dist_AB) ''' params = kwargs.copy() vasp_tmp = deepcopy(vasp) output = vasp_tmp\ (\ structure_tmp, outdir = join(outdir, join(str(step_todo), join("init", str(last_iter) ) )),\ relaxation = "static",\ **params ) output = vasp_tmp.Extract(join(outdir, join(str(step_todo), join("init", str(last_iter) ) ))) structure = output.structure assert output.success, RuntimeError("VASP run did not succeed.") structure_tmp = structure.copy() E = float(output.energy_sigma0) ''' disp = 0 for step, program in enumerate(programs[step_todo:]): print 'entering step', step params = kwargs.copy() params.update(program["vasp_param"]) vasp_tmp = deepcopy(vasp) if 'add_param' in program.keys(): for key in program['add_param'].keys(): if key not in vasp_tmp.__dict__['_input'].keys(): print key vasp_tmp.add_keyword(key, program['add_param'][key]) if 'vasp_param_final' in program.keys(): vasp_final = deepcopy(vasp) params_final = kwargs.copy() params_final.update(program["vasp_param_final"]) if 'add_param_final' in program.keys(): for key in program['add_param_final'].keys(): if key not in vasp_final.__dict__['_input'].keys(): print key vasp_final.add_keyword(key, program['add_param_final'][key]) for N in range(1, program["prog_param"]["Nstep"]+1): dir_out = join(outdir, join(str(step+step_todo), join("data", str(N+last_iter)+'_0' ) )) if os.path.isdir(dir_out): shutil.rmtree(dir_out, ignore_errors=True) print 'entering iter', N output = vasp_tmp\ (\ structure_tmp,\ outdir = dir_out,\ #relaxation = 'ionic',\ #relaxation = 'static',\ **params\ ) output = vasp_tmp.Extract(dir_out) assert output.success, RuntimeError("VASP run did not succeed.") if 'vasp_param_final' in program.keys(): output = vasp_final\ (\ output.structure,\ outdir = join(outdir, join(str(step+step_todo), join("data", str(N+last_iter) ) )),\ #relaxation = 'ionic',\ #relaxation = 'static',\ **params_final\ ) output = vasp_tmp.Extract(join(outdir, join(str(step+step_todo), join("data", str(N+last_iter)) )) ) assert output.success, RuntimeError("VASP run did not succeed.") fmax = deposit.get_mforce(output.structure) E_new = float(output.energy_sigma0) dE = E_new - E disp_final = str_util.get_disp(structure_tmp, output.structure) type_run = 'i' if 1: dE = E_new - E if dE <0: E = float(E_new) accept = 1 structure = output.structure.copy() structure_tmp = output.structure.copy() structure_min_e = output.structure.copy() N_min_e = N+last_iter else: A_move = np.exp( -beta * dE) if A_move > np.random.random(): E = float(E_new) accept = A_move structure = output.structure.copy() structure_tmp = output.structure.copy() else: structure_tmp = structure.copy() accept = 0 with Changedir(join(outdir, str(step+step_todo)) ) as pwd: #output.structure.write_poscar('poscar_%d'%N ) with open("energy.dat", "a") as file: tag = '%10d %10.5f %10.5f %10.3f %10.3f %10.3f %.2f %s %d\n' %(N + last_iter, E_new/Nat, dE/Nat, disp, disp_final, fmax, accept, type_run, N_min_e) file.write(tag) # need to print structure new if accept: with open("accept.dat", "a") as file: tag = '%10d %10.5f %10.5f %10.3f\n' %(N+last_iter, E_new/Nat, dE/Nat, disp_final) file.write(tag) # need to print structure new with open("traj.xyz", "a") as file: tag = 'disp %.3f' %(disp) file.write( move.print_to_xyz(structure, tag)) # need to print structure new else: #rmtree(join(outdir, join("data", str(N)))) pass with open("accept_all.dat", "a") as file: tag = '%10d %10.5f\n' %(N+last_iter, E/Nat) file.write(tag) # need to print structure new if program["prog_param"]["move_atoms"]: if mode == 'rls': move.move_atom(structure_tmp, move_type=move_type, seed=N+last_iter, min_dist_AA=min_dist_AA, min_dist_AB=min_dist_AB, relax = True) disp = str_util.get_disp(structure_tmp, structure) else: pass else: structure_tmp = output.structure.copy() if N == program["prog_param"]["Nstep"] and program["prog_param"]["move_atoms"]: structure = structure_min_e.copy() with Changedir(join(outdir, str(step+step_todo)) ) as pwd: with open("N_min_e.dat", "w") as file: tag = '%d' %(N_min_e) file.write( tag ) assert output.success, RuntimeError("VASP run did not succeed.") # performs final calculation output = vasp\ (\ structure, \ outdir = outdir,\ relaxation = "static",\ restart = output, \ **kwargs\ ) return Extract(outdir)