Example #1
0
    def bringdown(self, directory, structure):
        """ Copies contcar to outcar. """
        from os.path import exists
        from os import remove
        from ..misc import chdir

        logger.info('vasp/functional bringdown: directory: %s ' % directory)

        with chdir(directory):
            with open('pylada.FUNCTIONAL', 'w') as fout:
                fout.write(repr(self))

            if exists('.pylada_is_running'):
                remove('.pylada_is_running')
Example #2
0
    def bringdown(self, directory, structure):
        """ Copies contcar to outcar. """
        from os.path import exists
        from os import remove
        from ..misc import chdir

        logger.info('vasp/functional bringdown: directory: %s ' % directory)

        with chdir(directory):
            with open('pylada.FUNCTIONAL', 'w') as fout:
                fout.write(repr(self))

            if exists('.pylada_is_running'):
                remove('.pylada_is_running')
Example #3
0
    def bringup(self, structure, outdir, **kwargs):
        """ Creates all input files necessary to run results.

            Performs the following actions.

            - Writes POSCAR_ file.
            - Writes INCAR_ file.
            - Writes KPOINTS_ file.
            - Creates POTCAR_ file
        """
        from os.path import join
        from ..crystal import specieset
        from ..misc import chdir, local_path
        from . import files

        logger.info('vasp/functional bringup: outdir: %s ' % outdir)
        logger.debug('vasp/functional bringup: structure:\n%s' %
                     repr(structure))
        logger.debug('vasp/functional bringup: kwargs: %s' % repr(kwargs))

        with chdir(outdir):
            # creates INCAR file (and POSCAR via istruc).
            fpath = join(outdir, files.INCAR)
            logger.debug("vasp/functional bringup: incar fpath: %s " % fpath)
            self.write_incar(structure, path=fpath, outdir=outdir, **kwargs)

            # creates kpoints file
            logger.debug("vasp/functional bringup: files.KPOINTS: %s " %
                         files.KPOINTS)
            with open(files.KPOINTS, "w") as kp_file:
                self.write_kpoints(kp_file, structure)

            # creates POTCAR file
            logger.debug("vasp/functional bringup: files.POTCAR: %s " %
                         files.POTCAR)
            with open(files.POTCAR, 'w') as potcar:
                for s in specieset(structure):
                    outLines = self.species[s].read_potcar()
                    potcar.writelines(outLines)
            # Add is running file marker.
            local_path(outdir).join('.pylada_is_running').ensure(file=True)
            self._copy_additional_files(outdir)
Example #4
0
    def write_kpoints(self, file, structure, kpoints=None):
        """ Writes kpoints to a stream. """
        logger.info("vasp/functional write_kpoints: file: %s " % file)
        logger.debug("vasp/functional write_kpoints: kpoints: %s " % kpoints)

        if kpoints == None:
            kpoints = self.kpoints
        if isinstance(self.kpoints, str):
            file.write(self.kpoints)
        elif hasattr(self.kpoints, "__call__"):
            self.write_kpoints(file, structure, self.kpoints(self, structure))
        else:  # numpy array or such.
            outLine = "Explicit list of kpoints.\n{0}\nCartesian\n".format(
                len(self.kpoints))
            file.write(outLine)

            for kpoint in self.kpoints:
                outLine = "{0[0]} {0[1]} {0[2]} {1}\n".format(
                    kpoint, 1 if len(kpoint) == 3 else kpoint[3])
                file.write(outLine)
Example #5
0
    def write_kpoints(self, file, structure, kpoints=None):
        """ Writes kpoints to a stream. """
        logger.info("vasp/functional write_kpoints: file: %s " % file)
        logger.debug("vasp/functional write_kpoints: kpoints: %s " % kpoints)

        if kpoints == None:
            kpoints = self.kpoints
        if isinstance(self.kpoints, str):
            file.write(self.kpoints)
        elif hasattr(self.kpoints, "__call__"):
            self.write_kpoints(file, structure, self.kpoints(self, structure))
        else:  # numpy array or such.
            outLine = "Explicit list of kpoints.\n{0}\nCartesian\n".format(
                len(self.kpoints))
            file.write(outLine)

            for kpoint in self.kpoints:
                outLine = "{0[0]} {0[1]} {0[2]} {1}\n".format(
                    kpoint, 1 if len(kpoint) == 3 else kpoint[3])
                file.write(outLine)
Example #6
0
    def bringup(self, structure, outdir, **kwargs):
        """ Creates all input files necessary to run results.

            Performs the following actions.

            - Writes POSCAR_ file.
            - Writes INCAR_ file.
            - Writes KPOINTS_ file.
            - Creates POTCAR_ file
        """
        from os.path import join
        from ..crystal import specieset
        from ..misc import chdir, local_path
        from . import files

        logger.info('vasp/functional bringup: outdir: %s ' % outdir)
        logger.debug('vasp/functional bringup: structure:\n%s' % repr(structure))
        logger.debug('vasp/functional bringup: kwargs: %s' % repr(kwargs))

        with chdir(outdir):
            # creates INCAR file (and POSCAR via istruc).
            fpath = join(outdir, files.INCAR)
            logger.debug("vasp/functional bringup: incar fpath: %s " % fpath)
            self.write_incar(structure, path=fpath, outdir=outdir, **kwargs)

            # creates kpoints file
            logger.debug("vasp/functional bringup: files.KPOINTS: %s " % files.KPOINTS)
            with open(files.KPOINTS, "w") as kp_file:
                self.write_kpoints(kp_file, structure)

            # creates POTCAR file
            logger.debug("vasp/functional bringup: files.POTCAR: %s " % files.POTCAR)
            with open(files.POTCAR, 'w') as potcar:
                for s in specieset(structure):
                    outLines = self.species[s].read_potcar()
                    potcar.writelines(outLines)
            # Add is running file marker.
            local_path(outdir).join('.pylada_is_running').ensure(file=True)
            self._copy_additional_files(outdir)
Example #7
0
    def iter(self, structure, outdir=None, comm=None, overwrite=False, **kwargs):
        """ Allows asynchronous vasp calculations

            This is a generator which is equivalent to the following:

            .. code:: python

                yield Program(program="Vasp", outdir=outdir)
                yield Extract(outdir=outdir)

            - :py:class:`~pylada.process.program.ProgramProcess`: once started, this process will
               run an actual VASP_ calculation.
            - :py:attr:`Extract`: once the program has been runned, and extraction object is
              yielded, in order that the results of the run can be analyzed.


            This generator function makes it possible to run different instances of
            VASP_ simultaneously. It also makes it possible to create more complex
            calculations which necessitate more than one actual call to VASP_ (see
            :py:class:`~pylada.vasp.relax.iter_relax`), while retaining the ability
            to run multiple VASP_ programs simultaneously.

            If successful results (see :py:attr:`Extract.success`) already exist in
            outdir, Pylada defaults to *not* repeating the calculations. In that
            case, the first object described above is *skipped* and only an
            extraction object is yielded.

            The :py:meth:`__call__` method loops over this generator and makes
            actual VASP_ calls. Looking at its code is a good place to start, if
            you want to understand this looping business. The benefit of this
            approach can be seen in :py:class:`~pylada.vasp.relax.iter_relax` (more
            complex calculations) and
            :py:class:`pylada.process.jobfolder.JobFolderProcess`.

            :param structure:
                :py:class:`~pylada.crystal.Structure` structure to compute.
            :param outdir:
                Output directory where the results should be stored.  This
                directory will be checked for restart status, eg whether
                calculations already exist. If None, then results are stored in
                current working directory.
            :param comm:
                Holds arguments for executing VASP externally.
            :param overwrite:
                If True, will overwrite pre-existing results. 
                If False, will check whether a successful calculation exists. If
                one does, then does not execute. 
            :param kwargs:
                Any attribute of the VASP instance can be overridden for
                the duration of this call by passing it as keyword argument:

                >>> for program in vasp.iter(structure, outdir, sigma=0.5):
                ...

                The above would call VASP_ with smearing of 0.5 eV (unless a
                successfull calculation already exists, in which case the
                calculations are *not* overwritten). 

            :yields: A process and/or an extraction object, as described above.

            :raise RuntimeError: when computations do not complete.
            :raise IOError: when outdir exists but is not a directory.

            .. note::

                This function is stateless. It expects that self and structure can
                be deepcopied correctly.  

            .. warning:: 

                This will never overwrite successfull VASP calculation, even if the
                parameters to the call are different.
        """
        from ..process.program import ProgramProcess
        from .extract import Extract as ExtractVasp

        logger.info('vasp/functional iter: outdir: %s' % outdir)
        logger.debug('vasp/functional iter: structure:\n%s' % repr(structure))

        # check for pre-existing and successful run.
        if not overwrite:
            # Check with this instance's Extract, cos it is this calculation we shall
            # do here. Derived instance's Extract might be checking for other stuff.
            extract = Vasp.Extract(outdir)
            if extract.success:
                yield extract  # in which case, returns extraction object.
                return

        # copies/creates file environment for calculation.
        self.bringup(structure, outdir, comm=comm, overwrite=overwrite)

        # figures out what program to call.
        vaspProgram = getattr(self, 'program', None)
        if (vaspProgram == None):
            import pylada
            vaspProgram = pylada.vasp_program
        if vaspProgram == None:
            raise RuntimeError('program was not set in the vasp functional')

        if testValidProgram != None:
            vaspProgram = testValidProgram

        if hasattr(vaspProgram, '__call__'):
            vaspProgram = vaspProgram(self, structure, comm)
        # creates a process with a callback to bring-down environment once it is
        # done.

        def onfinish(process, error):  self.bringdown(outdir, structure)
        onfail = self.OnFail(Vasp.Extract(outdir))
        yield ProgramProcess(vaspProgram, cmdline=[], outdir=outdir,
                             onfinish=onfinish, onfail=onfail, stdout='stdout',
                             stderr='stderr', dompi=comm is not None)
        # yields final extraction object.
        yield ExtractVasp(outdir)
Example #8
0
    def iter(self,
             structure,
             outdir=None,
             comm=None,
             overwrite=False,
             **kwargs):
        """ Allows asynchronous vasp calculations

            This is a generator which is equivalent to the following:

            .. code:: python

                yield Program(program="Vasp", outdir=outdir)
                yield Extract(outdir=outdir)

            - :py:class:`~pylada.process.program.ProgramProcess`: once started, this process will
               run an actual VASP_ calculation.
            - :py:attr:`Extract`: once the program has been runned, and extraction object is
              yielded, in order that the results of the run can be analyzed.


            This generator function makes it possible to run different instances of
            VASP_ simultaneously. It also makes it possible to create more complex
            calculations which necessitate more than one actual call to VASP_ (see
            :py:class:`~pylada.vasp.relax.iter_relax`), while retaining the ability
            to run multiple VASP_ programs simultaneously.

            If successful results (see :py:attr:`Extract.success`) already exist in
            outdir, Pylada defaults to *not* repeating the calculations. In that
            case, the first object described above is *skipped* and only an
            extraction object is yielded.

            The :py:meth:`__call__` method loops over this generator and makes
            actual VASP_ calls. Looking at its code is a good place to start, if
            you want to understand this looping business. The benefit of this
            approach can be seen in :py:class:`~pylada.vasp.relax.iter_relax` (more
            complex calculations) and
            :py:class:`pylada.process.jobfolder.JobFolderProcess`.

            :param structure:
                :py:class:`~pylada.crystal.Structure` structure to compute.
            :param outdir:
                Output directory where the results should be stored.  This
                directory will be checked for restart status, eg whether
                calculations already exist. If None, then results are stored in
                current working directory.
            :param comm:
                Holds arguments for executing VASP externally.
            :param overwrite:
                If True, will overwrite pre-existing results. 
                If False, will check whether a successful calculation exists. If
                one does, then does not execute. 
            :param kwargs:
                Any attribute of the VASP instance can be overridden for
                the duration of this call by passing it as keyword argument:

                >>> for program in vasp.iter(structure, outdir, sigma=0.5):
                ...

                The above would call VASP_ with smearing of 0.5 eV (unless a
                successfull calculation already exists, in which case the
                calculations are *not* overwritten). 

            :yields: A process and/or an extraction object, as described above.

            :raise RuntimeError: when computations do not complete.
            :raise IOError: when outdir exists but is not a directory.

            .. note::

                This function is stateless. It expects that self and structure can
                be deepcopied correctly.  

            .. warning:: 

                This will never overwrite successfull VASP calculation, even if the
                parameters to the call are different.
        """
        from ..process.program import ProgramProcess
        from .extract import Extract as ExtractVasp

        logger.info('vasp/functional iter: outdir: %s' % outdir)
        logger.debug('vasp/functional iter: structure:\n%s' % repr(structure))

        # check for pre-existing and successful run.
        if not overwrite:
            # Check with this instance's Extract, cos it is this calculation we shall
            # do here. Derived instance's Extract might be checking for other stuff.
            extract = Vasp.Extract(outdir)
            if extract.success:
                yield extract  # in which case, returns extraction object.
                return

        # copies/creates file environment for calculation.
        self.bringup(structure, outdir, comm=comm, overwrite=overwrite)

        # figures out what program to call.
        vaspProgram = getattr(self, 'program', None)
        if (vaspProgram == None):
            import pylada
            vaspProgram = pylada.vasp_program
        if vaspProgram == None:
            raise RuntimeError('program was not set in the vasp functional')

        if testValidProgram != None:
            vaspProgram = testValidProgram

        if hasattr(vaspProgram, '__call__'):
            vaspProgram = vaspProgram(self, structure, comm)
        # creates a process with a callback to bring-down environment once it is
        # done.

        def onfinish(process, error):
            self.bringdown(outdir, structure)

        onfail = self.OnFail(Vasp.Extract(outdir))
        yield ProgramProcess(vaspProgram,
                             cmdline=[],
                             outdir=outdir,
                             onfinish=onfinish,
                             onfail=onfail,
                             stdout='stdout',
                             stderr='stderr',
                             dompi=comm is not None)
        # yields final extraction object.
        yield ExtractVasp(outdir)