Exemple #1
0
 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)
Exemple #2
0
 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)
Exemple #3
0
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)
Exemple #4
0
    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
Exemple #5
0
    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)
Exemple #7
0
    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
Exemple #8
0
 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)
Exemple #9
0
  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' )
Exemple #10
0
    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
Exemple #11
0
    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)
Exemple #12
0
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)