Ejemplo n.º 1
0
 def _dump_debugfile_info(self):
     from futile import YamlIO as Y
     debugfile = os.path.join('debug', 'bigdft-err-0.yaml')
     if os.path.isfile(debugfile):
         debugdict = Y.load(debugfile, doc_lists=False)
         safe_print('The error occured is', self._get_error_key(debugdict))
         safe_print('Additional Info: ', debugdict['Additional Info'])
Ejemplo n.º 2
0
 def __init__(self,
              omp=os.environ.get('OMP_NUM_THREADS', '1'),
              mpi_run=os.environ.get('BIGDFT_MPIRUN', ''),
              dry_run=False,
              skip=False,
              code="bigdft@localhost",
              verbose=True,
              **kwargs):
     Runner.__init__(self,
                     omp=str(omp),
                     mpi_run=mpi_run,
                     dry_run=dry_run,
                     skip=skip,
                     verbose=verbose,
                     **kwargs)
     # Build the command setting the number of omp threads
     self.code = load_code(code)
     self.job = BigDFTCalcJob
     # we don't want the executable and such
     self.command = ""
     # ignore this for datasets, as aiida splits each
     # computation in its own folder
     self.run_dir = "."
     # store logfiles and names in order to
     # skip execution if necessary.
     self.logfiles = {}
     # store output information on all runs.
     self.outputs = {}
     safe_print(
         'Initialize an Aiida Calculator for %s with %d machine(s)' %
         ((self.code), self._global_options.get('num_machines', 1)),
         ', %d processes per machine, and %s cores per process' %
         ((self._global_options.get('mpiprocs_per_machine',
                                    1), self._global_options['omp'])))
Ejemplo n.º 3
0
    def _posinp_dictionary_value(self, posinp):
        """
        Create the dictionary value associated to posinp field

        Args:
          posinp (str, dict): path of the posinp file. Might be relative or absolute. Copied into `run_dir` if not existing. If it is a dictionary, it is a representation
          of the atomic position.

        Returns:
          str,dict: the value of the key ``posinp`` of the input file, if posinp is a string, otherwise the posinp dictionary
        """
        import os
        from futile.Utils import ensure_copy, make_dict
        if isinstance(posinp, dict):
            return make_dict(posinp)
        # Check if the file does exist
        if not os.path.isfile(posinp):
            raise ValueError(
                "posinp: The atomic position file '%s' does not exist" %
                posinp)
        posinpdict = posinp
        posinpfile = os.path.basename(posinp)
        # Copy the posinp if not identical
        # LG: not like that "%s/%s" % (self.run_dir,posinp)
        cp_posinp = os.path.join(self.run_dir, posinpfile)
        copied = ensure_copy(src=posinp, dest=cp_posinp)
        if copied:
            posinpdict = posinpfile
            if self.run_options['verbose']:
                safe_print("Copy the posinp file '%s' into '%s'" %
                           (posinp, self.run_dir))
        return posinpdict
Ejemplo n.º 4
0
    def post_processing(self, timedbg, logname, command):
        """
        Check the existence and the log file and return an instance logfile.

        Returns:
           A `BigDFT.Logfile` class instance associated to the run which has been just performed.
           If the run failed for some reasons, the logfile seem not existing or it cannot be parsed it returns `None`.

        """
        # verify that no debug file has been created
        if self._get_debugfile_date() > timedbg:
            verbose = self.run_options['verbose']
            if verbose:
                safe_print(
                    "ERROR: some problem occured during the execution of the command, check the 'debug/' directory and the logfile"
                )
                # the debug file is sane, we may print out the error message
                self._dump_debugfile_info()
            try:
                return Lf.Logfile(logname)
            except:
                return None
        if os.path.exists(logname):
            from futile.Utils import file_time
            from time import time
            inputname = self._get_inputfilename()
            if file_time(logname) < file_time(
                    inputname) and not self.run_options['skip']:
                safe_print("ERROR: The logfile (", logname,
                           ") is older than the inputfile (", inputname, ").")
                return None
            else:
                return Lf.Logfile(logname)
        else:
            raise ValueError("The logfile (", logname, ") does not exist.")
    def _ensure_run_directory(self):
        from futile.Utils import ensure_dir
        run_dir = self.run_options.get('run_dir', '.')
        # Create the run_dir if not exist
        if ensure_dir(run_dir) and self.run_options['verbose']:
            safe_print("Create the sub-directory '%s'" % run_dir)

        self.run_dir = run_dir
def set_psp(name, psp):
        # Atoms
    import os
    pspfile = "psppar."+name
    dirname = os.path.dirname(__file__)
    filename =  os.path.join(dirname, "psppar", pspfile)
    if not os.path.isfile(filename):
        safe_print("WARNING: Using default PSP for atom", filename, name)
    else:
        psp.append(filename)
Ejemplo n.º 7
0
    def fill_from_xyz(self, file, nat_reference, fragmentation):
        """
        Import the fragment information from a xyz file

        Args:
           file (str): path of the ``xyz`` file to be opened
           nat_reference (int): number of atoms to be assigned to each of the fragments.
               Only useful in the case of uniform fragmentation
           fragmentation (list): contains the fragment identification as a list of ``['label', ats ]``
            where ``ats`` is a list of the atoms id associated to the fragment of label ``label``.
        """
        fil = open(file, 'r')
        nat = 0
        iat = 0
        frag = None
        ifrag = 0
        iline = 0
        for l in fil:
            iline += 1
            if iline == 2: continue
            try:
                pos = l.split()
                if len(pos) <= 2:  # these are the number of atoms
                    nt = int(pos[0])
                    nat -= nt
                    if len(pos) == 2:
                        unt = pos[1]
                        self._get_units(unt)
                    if frag is not None:
                        self.append(frag)
                    frag = Fragment(units=self.units)
                    iat = 0
                elif len(pos) > 0:
                    # we should break the fragment, alternative strategy
                    if nat_reference is not None:
                        nat_ref = nat_reference
                    elif fragmentation is not None:
                        nat_ref = len(fragmentation[ifrag][1])
                    else:
                        nat_ref = -1
                    if iat == nat_ref:
                        if frag is not None:
                            self.append(frag)
                        frag = Fragment(units=self.units)
                        if fragmentation is not None:
                            frag.set_id(fragmentation[ifrag][0])
                        iat = 0
                        ifrag += 1
                    frag.append({pos[0]: map(float, pos[1:])})
                    nat += 1
                    iat += 1
            except Exception, e:
                safe_print('Warning, line not parsed: "', l, e, '"')
Ejemplo n.º 8
0
 def _ensure_run_directory(self):
     from futile.Utils import ensure_dir
     run_dir = self.run_options.get('run_dir', '.')
     # Restrict run_dir to a sub-directory
     if ("/" in run_dir or run_dir == ".."):
         raise ValueError(
             "run_dir '%s' where bigdft is executed must be a sub-directory"
             % run_dir)
     # Create the run_dir if not exist
     if ensure_dir(run_dir) and self.run_options['verbose']:
         safe_print("Create the sub-directory '%s'" % run_dir)
     self.run_dir = run_dir
     """Run directory.
Ejemplo n.º 9
0
def rigid_transform_3D(A, B):
    "Find the transformation R and t such that R*A + t ~= B, with an error quantified by J"
    assert len(A) == len(B)

    N = A.shape[0]
    # total points

    centroid_A = mean(A, axis=0)
    centroid_B = mean(B, axis=0)

    #print 'centre',centroid_A,centroid_B
    # centre the points
    AA = A - tile(centroid_A, (N, 1))
    BB = B - tile(centroid_B, (N, 1))

    # dot is matrix multiplication for array
    H = transpose(AA) * BB

    #print 'H',H

    U, S, Vt = linalg.svd(H)

    R = Vt.T * U.T

    # special reflection case
    if linalg.det(R) < 0:
        safe_print("#Reflection detected")
        Vt[2, :] *= -1
        R = Vt.T * U.T

    t = -R * centroid_A.T + centroid_B.T

    #print t

    #identify also the accuracy of wahba
    A2 = R * A.T + tile(t, (1, N))
    A2 = A2.T

    # Find the error
    err = A2 - B

    err = multiply(err, err)
    err = sum(err)
    rmse = sqrt(err / N)

    return R, t, rmse
Ejemplo n.º 10
0
    def process_run(self, command):
        """
        Run the psi4 command.
        """
        from os import environ, system
        # Set the number of omp threads only if the variable is not present
        # in the environment
        if 'OMP_NUM_THREADS' not in environ:
            environ['OMP_NUM_THREADS'] = self.run_options['omp']

        if self.run_options['verbose']:
            if self.run_dir != '.':
                safe_print('Run directory', self.run_dir)

        # Run the command
        if command is not None:
            command()

        return {'logname': self._get_logname(True)}
Ejemplo n.º 11
0
    def process_run(self, command):
        """Finally launch the code.

        Routine associated to the running of the ``bigdft`` executable.

        Arguments:
           command (str): the command as it is set by the ``pre_processing`` method.
        """
        # check if the debug file will be updated (case of erroneous run)
        timedbg = self._get_debugfile_date()
        verbose = self.run_options['verbose']
        # Set the number of omp threads
        os.environ['OMP_NUM_THREADS'] = self.run_options['omp']
        if verbose:
            if self.run_dir != '.':
                safe_print('Run directory', self.run_dir)
            safe_print('Executing command: ', command)
        # Run the command
        os.system("cd " + self.run_dir + "; " + command)
        return {'timedbg': timedbg, 'logname': self._get_logname()}
Ejemplo n.º 12
0
    def pre_processing(self):
        # def run(self, name='', outdir='', run_name='', input={}, posinp=None,**kwargs):
        """
        Run a calculation building the input file from a dictionary.

        :param str name: naming scheme of the run i.e. <name>.yaml is the input file and log-<name>.yaml the output one.
           Data will then be written in the directory `data-<name>.yaml`, unless the "radical" keyword is specified in the input dictionary.
        :param str run_dir: specify the directory where bigdft will be executed (the input and log file will be created in it)
                            it must be a simple
        :param str outdir: specify the output directory for all data coming from bigdft (parameter of bigdft)
        :param str run_name: File containing the list of the run ids which have to be launched independently
                             (list in yaml format). The option runs-file is not compatible with the name option.
        :param input: give the input parameters (a dictionary or a list of dictionary)
        :type input: dict
        :param posinp: indicate the posinp file (atomic position file).
        :type posinp: filename
        :return: a Logfile instance is returned. It returns None if an error occurred
        :rtype: Logfile

        .. todo::

           Set the return value of run in the case of a run_file. It should be a list of Logfile classes

        """
        from futile.Utils import make_dict
        self._ensure_run_directory()
        # Create the input file (deepcopy because we modify it)
        inp = self.run_options.get('input', {})
        # from here onwards the local input is a dict and not anymore anothe class
        local_input = make_dict(inp)
        # Add into the dictionary a posinp key
        posinp = self.run_options.get('posinp', None)
        if posinp != None:
            local_input['posinp'] = self._posinp_dictionary_value(posinp)
        # Creating the yaml input file
        from futile import YamlIO as Y
        input_file = self._get_inputfilename()
        Y.dump(local_input, filename=input_file)
        if self.run_options['verbose']:
            safe_print('Creating the yaml input file "%s"' % input_file)
        return {'command': self._get_command()}
Ejemplo n.º 13
0
 def run(self, atoms=None, force=False):
     import os
     #To dump python object in a file
     import cPickle
     if atoms is None:
         atomlist = self.ortho
     else:
         atomlist = atoms
     #Loop over the elements
     #Test if the file bigdft-results.cpickle exists and use it instead
     if os.path.exists(cpickle_file) and not force:
         self.Elements = cPickle.load(open(cpickle_file, "r"))
     for name in atomlist:
         dico = self.Elements[name]
         if self.calculator.iproc == 0:
             safe_print("Start calculation of %s" % dico["name"])
         hgrid = 0.30
         var = set_inputfile(hgrid, dico)
         self.calculator.set(var)
         process_element(self.calculator, var, dico, force, self.Elements,
                         self.strains)
Ejemplo n.º 14
0
def process_element(run, var, dico, force_run, Elements, strains):
    import math
    import cPickle
    name = dico["name"]
    hgrids = var['dft']['hgrids']
    ngrids = (math.ceil(strains[0] * dico["a"] / hgrids[0]),
              math.ceil(strains[0] * dico["b"] / hgrids[1]),
              math.ceil(strains[0] * dico["c"] / hgrids[2]))
    for strain in strains:
        if run.iproc == 0:
            safe_print("(%s)" % strain)
        if strain in dico["eKS"] and not force_run:
            # The calculation is already done
            if run.iproc == 0:
                safe_print((name, strain), ": ", dico["eKS"][strain])
            continue
        var.update(InputGenerator.set_strain(strain, ngrids, dico))

        run.update(var)

        # Run and store the results
        out = run.run()

        var.update(InputGenerator.set_restart())

        run.update(var)
        # And restart
        out = run.run()

        Elements[name] = dico
        dico["eKS"][strain] = out.eKS
        dico["FKS"][strain] = out.etot
        dico["pressure"][strain] = out.pressure
        if run.iproc == 0:
            cPickle.dump(Elements, open(cpickle_file, "w"))
        # Parse the generated log to get the number of grid points.
        for l in open("log-%s.yaml" % var["radical"], "r"):
            if "Grid Spacing Units" in l:
                grid = l.split()
        ngrids = (int(grid[5][:-1]), int(grid[6][:-1]), int(grid[7]))
        ngrids = [a + 1 for a in ngrids]
    # Freeing memory
    run = None
    out = None
    # Build the file
    if run.iproc == 0:
        fd = open("%s.dat" % name, 'w')
        for strain in strains:
            dico = Elements[name]
            # Volume in A^3/atom
            volume = dico["volume"] * strain**3 / dico["nat"]
            HatoeV = 27.21138386
            eKS = float(dico["eKS"][strain]) * HatoeV / dico["nat"]
            fd.write("%16.9f %16.9f\n" % (volume, eKS))
            safe_print(strain, dico["eKS"][strain], volume, eKS)
        fd.close()
Ejemplo n.º 15
0
 def __init__(self,
              omp=os.environ.get('OMP_NUM_THREADS', '1'),
              mpi_run=os.environ.get('BIGDFT_MPIRUN', ''),
              dry_run=False,
              skip=False,
              verbose=True):
     # Use the initialization from the Runner class (so all options inside __global_options)
     Runner.__init__(self,
                     omp=str(omp),
                     mpi_run=mpi_run,
                     dry_run=dry_run,
                     skip=skip,
                     verbose=verbose)
     # Verify if $BIGDFT_ROOT is in the environment
     assert 'BIGDFT_ROOT' in os.environ
     executable = os.path.join(os.environ['BIGDFT_ROOT'], 'bigdft')
     # the bigdft file should be present in the BIGDFT_ROOT directory
     assert os.path.isfile(executable)
     # Build the command setting the number of omp threads
     self.command = (self._global_options['mpi_run'] + ' ' +
                     executable).strip()
     safe_print(
         'Initialize a Calculator with OMP_NUM_THREADS=%s and command %s' %
         (self._global_options['omp'], self.command))
Ejemplo n.º 16
0
def xyz_from_pymatgendict(dirXYZ, name, dico):
    import shutil
    import os
    import time
    format_xyz = """{1} reduced
 periodic {0[a]}   {0[b]}   {0[c]} 
"""
    #danger zone.. don't do ?
    if dirXYZ != ".":
        print("Remove the directory '%s'." % dirXYZ)
        shutil.rmtree(dirXYZ, ignore_errors=True)
    # Create it
    os.mkdir(dirXYZ)
    safe_print("---")
    # Start and create the xyz file
    # We have all the specification
    fnew = os.path.join(dirXYZ, name + ".xyz")  # "%s/%s.xyz" % (dirXYZ,name)
    fd = open(fnew, "w")
    nat = len(dico['sites'])
    fd.write(format_xyz.format(dico['lattice'], nat))
    for atom in dico['sites']:
        fd.write("%s " % atom['label'])
        fd.write("%f %f %f\n" % tuple(atom['xyz']))
    fd.close()
Ejemplo n.º 17
0
def set_inputfile(hgrid, dico):
    basicinput = """
logfile: Yes
dft:
    ixc: PBE
    ncong: 2
    rmult: [10, 8]
    itermax: 3
    idsx: 0
    gnrm_cv: 1e-8
#Control the diagonalisation scheme
mix:
    iscf: 7
    itrpmax: 200
    rpnrm_cv: 1e-12
    tel: 1e-3
    alphamix: 0.5
    norbsempty: 1000
    alphadiis: 1.0

#perf:
#    accel: OCLGPU
#    ocl_devices: Tesla K40c
#    blas: Yes

"""
    import yaml, os
    var = yaml.load(basicinput)
    #Spin parameters
    var["dft"].update(set_spin(dico["name"], dico["nat"]))
    #K point parameters
    var["kpt"] = set_kpoints(dico["nat"])
    var["dft"]["hgrids"] = (hgrid, hgrid, hgrid)
    #Control the diagonalisation scheme
    if dico["name"] in ("Cr", ):
        var["mix"]["iscf"] = 3
        var["mix"]["alphamix"] = 0.9
    if dico["name"] in ("Ba", "Ca"):
        var["mix"]["norbsempty"] = 8
    var["ig_occupation"] = {dico["name"]: {"empty_shells": ("s", "p", "d")}}
    #Atoms
    pspfile = "psppar." + dico["name"]
    if not os.path.isfile(pspfile):
        safe_print("WARNING: Using default PSP for atom", dico["name"])
    else:
        var[pspfile] = open(pspfile, 'r').read()
    #var["posinp"] = {"positions": [{dico["name"]: map(float, dico[i + 1].split())} for i in range(dico["nat"])], "units": "reduced", "cell": (dico["a"], dico["b"], dico["c"])}
    var["posinp"] = {
        "positions": [{
            dico["name"]: dico[i + 1]
        } for i in range(dico["nat"])],
        "units": "reduced",
        "cell": (dico["a"], dico["b"], dico["c"])
    }
    # We round robin the igspins.
    if "mpol" in var["dft"]:
        mpol = 0
        while mpol < var["dft"]["mpol"]:
            for at in var["posinp"]["positions"]:
                if mpol < var["dft"]["mpol"]:
                    if "IGSpin" in at:
                        at["IGSpin"] += 1
                    else:
                        at["IGSpin"] = 1
                    mpol += 1
    elif "nspin" in var["dft"] and var["dft"]["nspin"] == 2:
        for (i, at) in enumerate(var["posinp"]["positions"]):
            at["IGSpin"] = 1 - 2 * (i % 2)
    return var
Ejemplo n.º 18
0
def _example():
    """Test the XYZ Module"""
    from BigDFT.Systems import System
    from BigDFT.Fragments import Fragment
    from BigDFT.UnitCells import UnitCell
    file = "Si4"

    safe_print("First let's try reading an XYZ file.")
    atom_list = []
    with XYZReader(file) as reader:
        safe_print(reader.closed)
        for at in reader:
            atom_list.append(at)
    safe_print(reader.closed)
    safe_print(atom_list)
    safe_print()

    safe_print("Now let's try writing an XYZ file.")
    safe_print()
    with XYZWriter("test.xyz", len(atom_list),
                   units=reader.units) as writer:
        safe_print(writer.closed)
        for at in atom_list:
            writer.write(at)
    safe_print(writer.closed)
    safe_print()
    with open("test.xyz") as ifile:
        for line in ifile:
            safe_print(line, end='')
    safe_print()

    safe_print("Print with various boundary conditions")
    with XYZWriter("test.xyz", len(atom_list), reader.units,
                   cell=UnitCell()) as writer:
        for at in atom_list:
            writer.write(at)
    with XYZReader("test.xyz") as ifile:
        print(ifile.cell.get_boundary_condition())

    with XYZWriter("test.xyz", len(atom_list), reader.units,
                   cell=UnitCell([5, 5, 5])) as writer:
        for at in atom_list:
            writer.write(at)
    with XYZReader("test.xyz") as ifile:
        print(ifile.cell.get_boundary_condition())

    with XYZWriter("test.xyz", len(atom_list), reader.units,
                   cell=UnitCell([5, float("inf"), 5])) as writer:
        for at in atom_list:
            writer.write(at)
    with XYZReader("test.xyz") as ifile:
        print(ifile.cell.get_boundary_condition())

    with XYZWriter("test.xyz", len(atom_list), reader.units,
                   cell=UnitCell([float("inf"), float("inf"), 5])) as writer:
        for at in atom_list:
            writer.write(at)
    with XYZReader("test.xyz") as ifile:
        print(ifile.cell.get_boundary_condition())
    safe_print()

    safe_print("Now let's demonstrate the pdb and mol2 writer")
    sys = System()
    sys["FRAG:0"] = Fragment(atom_list)
    with open("test.pdb", "w") as ofile:
        write_pdb(sys, ofile)
    with open("test.pdb") as ifile:
        for line in ifile:
            safe_print(line, end='')
    safe_print()

    with open("test.mol2", "w") as ofile:
        write_mol2(sys, ofile)
    with open("test.mol2") as ifile:
        for line in ifile:
            safe_print(line, end='')
    safe_print()
Ejemplo n.º 19
0
def xyz_from_elements(dirXYZ, Elements, ortho, nonortho):
    import shutil, os, time
    format_xyz = """{0[nat]} reduced
 periodic {0[a]}   {0[b]}   {0[c]} 
"""
    #print "Remove the directory '%s'." % dirXYZ
    shutil.rmtree(dirXYZ, ignore_errors=True)
    #Create it
    os.mkdir(dirXYZ)
    safe_print("---")
    #Start and create the xyz files
    safe_print("Delta-test timestamp:", time.strftime('%X %x %Z'))
    safe_print("Delta-test code: BigDFT")
    safe_print("Number of elements: ", len(Elements))
    safe_print("List of elements:", Elements.keys())
    safe_print("Number of orthorhombic elements: ", len(ortho))
    safe_print("Orthorhombic elements: ", ortho)
    safe_print("Number of non-orthorhombic elements: ", len(nonortho))
    safe_print("Non-orthorhombic elements: ", nonortho)
    for dico in Elements.values():
        name = dico['name']
        #We have all the specification
        fnew = os.path.join(dirXYZ,
                            name + ".xyz")  #"%s/%s.xyz" % (dirXYZ,name)
        fd = open(fnew, "w")
        fd.write(format_xyz.format(dico))
        for i in range(dico['nat']):
            fd.write("%s " % name)
            fd.write("%f %f %f\n" % tuple(dico[i + 1]))
            #fd.write("%s %s\n" % (name,dico[i+1]))
        fd.close()