Beispiel #1
0
def plot_history(abinitfile, dataset=""):
    history = get_history(abinitfile, dataset)
    av = InputVariables(abinitfile.get_input_filename())

    if dataset == "":
        filep = abinitfile.basedir + "/" + abinitfile.files['tmpout'] + ".pdf"
    else:
        filep = abinitfile.basedir + "/" + abinitfile.files[
            'tmpout'] + "_DS" + str(dataset) + ".pdf"

    xcart = history.variables['xcart'][:]
    fcart = history.variables['fcart'][:]
    # rprimd = history.variables['rprimd'][:]
    etotal = history.variables['etotal'][:]
    if 'ekin' in history.variables:
        ekin = history.variables['ekin'][:]
        if max(history.variables['ekin'][:]) == 0.0:
            ekin = None
    else:
        ekin = None

    # Getting Labels of atoms
    labels = [av.atom_name(i) for i in range(av.get_value('natom', dataset))]
    znucl = av.get_value('znucl', idtset=dataset)
    typat = av.get_value('typat', idtset=dataset)

    bonds = compute_bonds(typat, xcart, znucl)
    # natom = len(xcart[0])
    # ComputeAngles(bonds,natom)

    plot_history_energy(etotal, ekin, fcart, labels, bonds, filep)
Beispiel #2
0
def structure_from_file(structure_file):
    st = None
    if not os.path.isfile(structure_file):
        print("ERROR: Could not open file '%s'" % structure_file)
        sys.exit(1)
    if structure_file[-4:].lower() == 'json':
        st = Structure.load_json(structure_file)
    elif structure_file[-3:].lower() == 'cif' and HAS_PYMATGEN:
        import pychemia.external.pymatgen
        st = pychemia.external.pymatgen.cif2structure(structure_file)[0]
    elif structure_file[-6:].lower() == 'poscar':
        st = read_poscar(structure_file)
    elif structure_file[-6:].lower() == 'contcar':
        st = read_poscar(structure_file)
    elif structure_file[-6:].lower() == 'abinit.in':
        av = InputVariables(structure_file)
        av.get_structure()
    else:
        try:
            st = read_poscar(structure_file)
        except ValueError:
            print("ERROR: Could not extract structure from file '%s'" %
                  structure_file)
            exit(1)
    return st
Beispiel #3
0
def plot_bonds(listabifile, listidtset):
    pp = PdfPages("bonds.pdf")
    plt.ioff()

    if not listidtset:
        allbonds = get_all_bonds(listabifile)
    else:
        allbonds = get_all_bonds(listabifile, listidtset)
    plt.figure(figsize=(32, 20), dpi=100)
    plt.subplots_adjust(left=0.05,
                        bottom=0.05,
                        right=0.95,
                        top=0.95,
                        wspace=None,
                        hspace=None)

    abivar = InputVariables(listabifile[0].get_input_filename())

    nbond = len(allbonds[0])
    n = 0
    for ibond in allbonds:
        if len(ibond) != nbond:
            print('ERROR: Number of bonds changed')
            if not listidtset:
                print(
                    (listabifile[n].basedir, 'contains', len(ibond), 'bonds'))
            else:
                print(
                    (listabifile[n].filename + ':' + listidtset[n], 'contains',
                     len(ibond), 'bonds'))
                n += 1

    iplot = 1
    for ibond in range(nbond):
        plt.subplot(5, 4, iplot)
        y = [bohr_angstrom * seti[ibond][2] for seti in allbonds]
        label = abivar.atom_name(seti[ibond][0]) + ' ' + abivar.atom_name(
            seti[ibond][1])
        plt.plot(y, label=label)
        plt.plot(y, 'ro')
        iplot += 1
        plt.legend()

    pp.savefig()
    plt.clf()

    for ibond in range(nbond):
        y = [bohr_angstrom * seti[ibond][2] for seti in allbonds]
        label = abivar.atom_name(seti[ibond][0]) + ' ' + abivar.atom_name(
            seti[ibond][1])
        plt.plot(y, label=label)
        plt.plot(y, 'ro')

        plt.text(0.09, y[0] + 0.001, label, size='small')
        iplot += 1
        plt.legend()

    pp.savefig()
    pp.close()
Beispiel #4
0
    def prepare_folder(self, entry_id, workdir='.', source_dir='.'):
        """
        Prepare directories for abinit execution

        :param entry_id:    bson.ObjectID of the entry that will be used for preparing the folder
        :param source_dir: (str) is the directory where 'abinit.files' and 'batch.pbs' should be present
                           those directories will be symbolically linked inside the individual work directories
        :param workdir: (str) Base work directory for abinit executions. Inside this directory, a set of subdirectories
                              will be created using the mongo ID as name.

        """
        # Individual workdir
        iworkdir = workdir + os.sep + str(entry_id)

        if not os.path.isdir(iworkdir):
            os.mkdir(iworkdir)

        if os.path.lexists(iworkdir + os.sep + 'abinit.files'):
            os.remove(iworkdir + os.sep + 'abinit.files')
        if not os.path.isfile(source_dir + os.sep + 'abinit.files'):
            print(
                'WARNIG: The file %s should be present on %s, symbolic links will be created pointing '
                'to that location' % ('abinit.files', source_dir))
        os.symlink(os.path.abspath(source_dir + os.sep + 'abinit.files'),
                   iworkdir + os.sep + 'abinit.files')

        abiinput = InputVariables(self.input_path)
        params = self.get_correlation_params(entry_id, final=False)
        dmatpawu = params2dmatpawu(params)
        abiinput['dmatpawu'] = list(dmatpawu.flatten())
        abiinput.write(iworkdir + os.sep + 'abinit.in')

        d_abiinput = InputVariables(iworkdir + os.sep + 'abinit.in')
        d_dmatpawu = d_abiinput['dmatpawu']
        assert (d_dmatpawu is not None)
        d_params = dmatpawu2params(d_dmatpawu, self.ndim)
        if not np.all(
                np.sum(d_params['occupations'], axis=1) == np.array(
                    self.num_electrons_dftu)):
            print(
                'ERROR: Inconsistent number of DFT+U electrons for correlated orbitals: %s'
                % entry_id)
            print('From the population: %s ' % self.num_electrons_dftu)
            print('From "abinit.in":    %s ' % d_params['occupations'])
Beispiel #5
0
def get_all_bonds(abinitfile, dtset=''):
    allbonds = []
    index = 0
    for abf in abinitfile:
        if dtset == '':
            idt = ''
        else:
            idt = int(dtset[index])
            index += 1
        filep = abf.basedir + "/" + abf.files['tmpout'] + "_OUT.nc"

        out = InputVariables(filep)

        xcart = out.get_value('xcart', idtset=idt)
        znucl = out.get_value('znucl', idtset=idt)
        typat = out.get_value('typat', idtset=idt)

        bonds = compute_bonds(typat, xcart, znucl)
        allbonds.append(bonds)

    abivar = InputVariables(abinitfile[0].get_input_filename())
    save_bonds(allbonds, abivar)
    return allbonds
Beispiel #6
0
def test_abinit_input():
    """
    Tests (pychemia.code.abinit) [input]                         :
    """
    if pychemia.HAS_SCIPY and pychemia.HAS_SCIENTIFIC:
        from pychemia.code.abinit import AbiFiles, InputVariables

        filename = "pychemia/test/data/abinit_01/abinit.files"
        abf = AbiFiles(filename)
        inp = InputVariables(abf)
        print(inp)
        print(len(inp))
        assert len(inp) == 31
        assert inp.get_value('ecut') == 10
        assert len(inp.get_dtsets_keys()) == 12
        assert inp.get_value('ntime', 41) == 10
        assert inp.get_value('acell', 41)[0] == 14
Beispiel #7
0
    def __init__(self,
                 name,
                 abinit_input='abinit.in',
                 natpawu=None,
                 oxidations=None):

        Population.__init__(self, name, 'global')
        if not os.path.isfile(abinit_input):
            print("Abinit input not found")
            raise ValueError
        self.input = InputVariables(abinit_input)
        self.structure = self.input.get_structure()
        self.maxlpawu = max(self.input.get_value('lpawu'))

        if natpawu is None:
            spinat = self.input.get_value('spinat')
            if spinat is None:
                print(
                    'I could not determine the number of atoms playing a role in the DFT+U calculation'
                )
                raise ValueError('Could not determine natpawu')
            else:
                spinat = np.array(spinat).reshape((-1, 3))
                self.natpawu = np.sum(
                    np.apply_along_axis(np.linalg.norm, 1, spinat) != 0)
        else:
            self.natpawu = natpawu
        if self.input.has_variable('nsppol'):
            self.nsppol = self.input.get_value('nsppol')
        else:
            self.nsppol = 1
        if self.input.has_variable('nspinor'):
            self.nspinor = self.input.get_value('nspinor')
        else:
            self.nspinor = 1

        self.oxidations = oxidations
        self.connection = [1, -1, -1, 1]
Beispiel #8
0
if __name__ == '__main__':

    narg = len(sys.argv) - 1

    list_abifile = []
    list_idtset = []
    dtsetall = False
    for i in range(narg):
        filename = sys.argv[i + 1]
        if ':' in filename:
            idtset = filename.split(':')[1]
            if idtset == 'all':
                dtsetall = True
            else:
                list_idtset.append(idtset)
            filename = filename.split(':')[0]

        abifile = AbiFiles(filename)
        if dtsetall:
            av = InputVariables(abifile.get_input_filename())
            keys = av.get_dtsets_keys()
            for j in keys:
                list_abifile.append(abifile)
                list_idtset.append(str(j))

        else:
            list_abifile.append(abifile)

    plot_bonds(list_abifile, list_idtset)
Beispiel #9
0
    def __init__(self,
                 name,
                 input_path='abinit.in',
                 num_electrons_dftu=None,
                 num_indep_matrices=None,
                 connections=None):
        """
        This population is created with the purpose of global optimization of correlated orbitals 'd'
        and 'f'.


        The population is basically a collection of ABINIT inputs, the candidates have the same structure and
        uses the same input variables with exception of 'dmatpawu', the purpose of the
        population is to use global-population searchers to find the correlation matrices
        'dmatpawu' that minimizes the energy.

        The variable 'dmatpawu' is a list of numbers that can be arranged into N matrices.
        The matrices are 5x5 for 'd' orbitals and 7x7 for 'f' orbitals.

        :param name: The name of the 'PyChemiaDB' database created to stored the different
                        set of variables and the resulting output from abinit.
                     When using databases protected with username and password, the database
                        should be created independently and the database object must be use
                        as the 'name' argument

        :param input_path: The abinit input file, all the variables will be preserve for all new candidates, except
                        for 'dmatpawu' the only variable that changes.

        :param num_electrons_dftu: Example [5, 1, 5, 1]

        """
        # Call the parent class initializer to link the PyChemiaDB that will be used
        Population.__init__(self, name, 'global', distance_tolerance=0.1)
        # Checking for existence of 'abinit.in'
        if not os.path.isfile(input_path):
            raise ValueError("Abinit input not found")
        # Reading the input variables and getting the structure
        self.input_path = input_path
        self.input = InputVariables(input_path)
        if 'dmatpawu' not in self.input.variables:
            raise ValueError(
                "Abinit input file does not contain 'dmatpawu' variable")
        self.structure = self.input.get_structure()

        print('Orbital population:')
        print('Species [znucl]: %s' % self.input['znucl'])

        self.natpawu = 0
        print('Orbitals corrected:')
        for i in range(self.input['ntypat']):
            if self.input['lpawu'][i] == -1:
                print("%3s : False" % self.input['znucl'][i])
            else:
                print("%3s : True (l=%d)" %
                      (self.input['znucl'][i], self.input['lpawu'][i]))
                self.natpawu += sum(
                    [1 for x in self.input['typat'] if x == i + 1])
        print('Number of atoms where DFT+U is applied: %d' % self.natpawu)

        # Computing the orbital that will be corrected
        # 2 (d-orbitals) or 3 (f-orbitals)
        self.maxlpawu = max(self.input['lpawu'])
        if self.maxlpawu == 2:
            print("Correlation of 'd' orbitals")
        elif self.maxlpawu == 3:
            print("Correlation of 'f' orbitals")

        # nsppol is the number of independent spin polarisations. Can take the values 1 or 2
        if self.input.has_variable('nsppol'):
            self.nsppol = self.input.get_value('nsppol')
        else:
            # Default from ABINIT
            self.nsppol = 1

        # nspinor it the umber of spinorial components of the wavefunctions
        if self.input.has_variable('nspinor'):
            self.nspinor = self.input.get_value('nspinor')
        else:
            self.nspinor = 1

        # nspden is the number of spin-density components
        if self.input.has_variable('nspden'):
            self.nspden = self.input.get_value('nspden')
        else:
            self.nspden = self.nsppol

        if self.nsppol == 1 and self.nspinor == 1 and self.nspden == 1:
            # Non-magnetic system (nsppol=1, nspinor=1, nspden=1):
            # One (2lpawu+1)x(2lpawu+1) dmatpawu matrix is given for each atom on which +U is applied.
            # It contains the "spin-up" occupations.
            self.nmatrices = self.natpawu
        elif self.nsppol == 2 and self.nspinor == 1 and self.nspden == 2:
            # Ferromagnetic spin-polarized (collinear) system (nsppol=2, nspinor=1, nspden=2):
            # Two (2lpawu+1)x(2lpawu+1) dmatpawu matrices are given for each atom on which +U is applied.
            # They contain the "spin-up" and "spin-down" occupations.
            self.nmatrices = 2 * self.natpawu
        elif self.nsppol == 1 and self.nspinor == 1 and self.nspden == 2:
            # Anti-ferromagnetic spin-polarized(collinear) system(nsppol=1, nspinor=1, nspden=2):
            # One(2lpawu + 1)x(2lpawu + 1) dmatpawu matrix is given for each atom on which +U is applied.
            # It contains the "spin-up" occupations.
            self.nmatrices = self.natpawu
        elif self.nsppol == 1 and self.nspinor == 2 and self.nspden == 4:
            # Non-collinear magnetic system (nsppol=1, nspinor=2, nspden=4):
            # Two (2lpawu+1)x(2lpawu+1) dmatpawu matrices are given for each atom on which +U is applied.
            # They contains the "spin-up" and "spin-down" occupations (defined as n_up=(n+|m|)/2 and n_dn=(n-|m|)/2),
            #    where m is the integrated magnetization vector).
            self.nmatrices = 2 * self.natpawu
        elif self.nsppol == 1 and self.nspinor == 2 and self.nspden == 1:
            # Non-collinear magnetic system with zero magnetization (nsppol=1, nspinor=2, nspden=1):
            # Two (2lpawu+1)x(2lpawu+1) dmatpawu matrices are given for each atom on which +U is applied.
            # They contain the "spin-up" and "spin-down" occupations;
            self.nmatrices = 2 * self.natpawu

        print('Variables controling the total number of matrices')
        print('nsppol : %d' % self.nsppol)
        print('nspinor: %d' % self.nspinor)
        print('nspden : %d' % self.nspden)
        print('Total number of matrices expected on dmatpawu: %d' %
              self.nmatrices)

        if num_electrons_dftu is None:
            abiinput = InputVariables(input_path)
            dmatpawu = np.array(abiinput['dmatpawu']).reshape(
                -1, self.ndim, self.ndim)
            params = dmatpawu2params(dmatpawu, 5)
            self.num_electrons_dftu = np.apply_along_axis(
                sum, 1, params['occupations'])
        else:
            self.num_electrons_dftu = np.array(num_electrons_dftu)
        print('Number of electrons for each correlation matrix: %s' %
              self.num_electrons_dftu)

        if num_indep_matrices is not None:
            self.num_indep_matrices = num_indep_matrices
        else:
            self.num_indep_matrices = self.nmatrices

        self.num_electrons_dftu = [int(x) for x in self.num_electrons_dftu]
        print('Number of independent matrices: %d' % self.num_indep_matrices)

        if connections is not None:
            self.connections = list(connections)
            if len(self.connections) != self.nmatrices:
                raise ValueError(
                    'Number of connections between matrices is not consistent with the number of matrices '
                    'defined on dmatpawu')
            print('Connections: %s' % self.connections)
        else:
            self.connections = list(range(self.nmatrices))