Source code for storq.vasp.runner

import numpy as np
import os
import warnings

from storq.tools import getstatusoutput


[docs] class Runner: def _get_runcmd(self): """Determine the appropriate run command for vasp. Builds up a list of commands to run the appropriate vasp version (std, ncl, gamma) with or without mpi. If mpi is used the number of procs is determined automatically if the standard mpirun is used. Returns ------- list A list of commands that can be passed to subprocess in order to run vasp. """ conf = self.conf site = self.siteconf mpi_command = conf.get("mpi_command", None) # determine the appropriate vasp version kpts = self.parameters.get("kpts", None) # kspacing = self.parameters.get("kspacing", None) ncl = self.parameters.get("lnoncollinear", None) if ncl: if self.conf.get("vasp_executable_ncl", None): executable = conf["vasp_executable_ncl"] else: raise RuntimeError( ( "vasp_executable_ncl must be set in order" "to run non-collinear calculations" ) ) elif "size" in kpts and np.all(np.equal(kpts["size"], np.array([1, 1, 1]))): if conf.get("vasp_executable_gam", None): executable = conf["vasp_executable_gam"] else: executable = conf["vasp_executable_std"] else: executable = conf["vasp_executable_std"] if mpi_command: vasp_runcmd = [mpi_command] mpi_options = conf.get("mpi_options", None) # if mpi options are specified we check if they contain an accepted # proc count flag else determine the count automatically if mpi_options is None: mpi_options = "" mpi_options_split = mpi_options.split() vasp_runcmd += [option for option in mpi_options_split] mpi_proc_flags = ["-n", "-np"] # add automatic core counting only if needed if ( conf.get("mpi_count_cores", False) and site["env"]["nodelist"] in os.environ ): if set(mpi_proc_flags).isdisjoint(set(mpi_options_split)): vasp_runcmd += ["-n", str(self.get_ntasks())] vasp_runcmd += [executable] else: # no MPI and running at cl vasp_runcmd = [executable] return vasp_runcmd def _run(self): """ If this is called, then the calculator thinks a job should be run. If we are in the queue, we should run it, otherwise, a job should be submitted. """ conf = self.conf site = self.siteconf cwd = os.getcwd() self.write_input() self.write_persistence_db(self.atoms) if conf["vasp_mode"] == "run" or ( site and site["env"]["submitdir"] in os.environ ): # we get the run command and run vasp here os.chdir(self.directory) vasp_runcmd = self._get_runcmd() if conf.get("vasp_stdout", "vasp.out"): with open(conf["vasp_stdout"], "wb") as fout: retcode = getstatusoutput(vasp_runcmd, stdout=fout, stderr=fout) # state will be changed after running so we must update it self.state = self.get_state() if self.state == self.UNCONVERGED: warnings.warn( "{0}: Calculation is not converged".format(self.directory), UserWarning, ) elif self.state == self.UNFINISHED: warnings.warn( "{0}: Vasp did not finish".format(self.directory), UserWarning ) self.read_results() os.chdir(cwd) return retcode # if we are in queue vasp_mode we should submit a job elif conf["vasp_mode"] == "queue": file_args = "{} {}".format(cwd, self.directory) self.submit("runvasp.py", file_args)