示例#1
0
def dftb_read_input(folder):
    """Read a DFTB+ output non-destructively.

    Args:
      directory (str): path to a directory to load DFTB+ results

    Returns:
      atoms (ase.Atoms): an atomic structure with the results attached in a
      SinglePointCalculator
    """

    atoms = io.read(os.path.join(folder, 'geo_end.gen'))
    atoms.info['name'] = os.path.split(folder)[-1]
    results_file = os.path.join(folder, "results.tag")
    if os.path.isfile(results_file):
        # DFTB+ was used to perform the optimisation
        temp_file = os.path.join(folder, "results.tag.bak")

        # We need to backup the results file here because
        # .read_results() will remove the results file
        with BackupFile(results_file, temp_file):
            calc = Dftb(atoms=atoms)
            calc.atoms_input = atoms
            calc.directory = folder
            calc.do_forces = True
            try:
                calc.read_results()
            except:
                # Failed for ANY reason
                atoms.set_calculator(None)
                return atoms

        energy = calc.get_potential_energy()
        forces = calc.get_forces()
        charges = calc.get_charges(atoms)

        calc = SinglePointCalculator(atoms,
                                     energy=energy,
                                     forces=forces,
                                     charges=charges)

        atoms.set_calculator(calc)

    return atoms
示例#2
0
def create_spinpol_dftbp_calculator(calc=None, param_set='3ob-3-1', kpts=None):
    """Create a calculator containing all necessary parameters for a DFTB+
    SCC spin polarised calculation"""
    from pymuonsuite.data.dftb_pars import DFTBArgs

    if not isinstance(calc, Dftb):
        calc = Dftb()
    else:
        calc = deepcopy(calc)

    # A bit of a hack for the k-points
    if kpts is not None:
        kc = Dftb(kpts=kpts)
        kargs = {k: v for k, v in kc.parameters.items() if 'KPoints' in k}
        calc.parameters.update(kargs)

    # Create the arguments
    dargs = DFTBArgs(param_set)
    # Make it spin polarised
    try:
        dargs.set_optional('spinpol.json', True)
    except KeyError:
        raise ValueError('DFTB+ parameter set does not allow spin polarised'
                         ' calculations')
    # Fix a few things, and add a spin on the muon
    args = dargs.args
    del (args['Hamiltonian_SpinPolarisation'])
    args['Hamiltonian_SpinPolarisation_'] = 'Colinear'
    args['Hamiltonian_SpinPolarisation_UnpairedElectrons'] = 1
    args['Hamiltonian_SpinPolarisation_InitialSpins_'] = ''
    args['Hamiltonian_SpinPolarisation_InitialSpins_Atoms'] = '-1'
    args['Hamiltonian_SpinPolarisation_InitialSpins_SpinPerAtom'] = 1

    calc.parameters.update(args)
    calc.do_forces = True

    return calc
示例#3
0
    def read(self, folder, sname=None, read_spinpol=False, read_phonons=False,
             **kwargs):
        ''' Read a DFTB+ output non-destructively.
        |
        |   Args:
        |   folder (str) :          path to a directory to load DFTB+ results
        |   sname (str):            name to label the atoms with and/or of the
        |                           .phonons.pkl file to be read
        |   Returns:
        |   atoms (ase.Atoms):      an atomic structure with the results
        |                           attached in a SinglePointCalculator
        '''

        try:
            with silence_stdio():
                atoms = io.read(os.path.join(folder, 'geo_end.gen'))

        except IOError:
            raise IOError("ERROR: No geo_end.gen file found in {}."
                          .format(os.path.abspath(folder)))
        except Exception as e:
            raise IOError("ERROR: Could not read {file}, due to error: {error}"
                          .format(file='geo_end.gen', error=e))
        if sname is None:
            atoms.info['name'] = os.path.split(folder)[-1]
        else:
            atoms.info['name'] = sname
        results_file = os.path.join(folder, "results.tag")
        if os.path.isfile(results_file):
            # DFTB+ was used to perform the optimisation
            temp_file = os.path.join(folder, "results.tag.bak")

            # We need to backup the results file here because
            # .read_results() will remove the results file
            with BackupFile(results_file, temp_file):
                calc = Dftb(atoms=atoms)
                calc.atoms_input = atoms
                calc.directory = folder
                calc.do_forces = True
                calc.read_results()

            energy = calc.get_potential_energy()
            forces = calc.get_forces()
            charges = calc.get_charges(atoms)

            calc = SinglePointCalculator(atoms, energy=energy,
                                         forces=forces, charges=charges)

            atoms.calc = calc

        if read_spinpol:
            try:
                pops = parse_spinpol_dftb(folder)
                hfine = []
                for i in range(len(atoms)):
                    hf = compute_hfine_mullpop(atoms, pops, self_i=i,
                                               fermi=True, fermi_neigh=True)
                    hfine.append(hf)
                atoms.set_array('hyperfine', np.array(hfine))
            except (IndexError, IOError) as e:
                raise IOError('Could not read hyperfine details due to error: '
                              '{0}'.format(e))

        if read_phonons:
            try:
                if sname is not None:
                    phonon_source_file = os.path.join(folder, sname +
                                                      '.phonons.pkl')
                else:
                    print("Phonons filename was not given, searching for any"
                          " .phonons.pkl file.")
                    phonon_source_file = glob.glob(
                        os.path.join(folder, '*.phonons.pkl'))[0]
                self._read_dftb_phonons(atoms, phonon_source_file)
            except IndexError:
                raise IOError("No .phonons.pkl files found in {}."
                              .format(os.path.abspath(folder)))
            except IOError:
                raise IOError("{} could not be found."
                              .format(phonon_source_file))
            except Exception as e:
                raise IOError('Could not read {file} due to error: {error}'
                              .format(file=phonon_source_file, error=e))

        return atoms