Exemplo n.º 1
0
    def test_read_from_file(self):
        # no becs, so no splitting. The test only checks the parsing
        ddb = DdbFile(os.path.join(test_dir, "ZnO_gamma_becs_DDB"))

        phbands = ddb.anaget_phmodes_at_qpoint(qpoint=[0, 0, 0], lo_to_splitting=True)

        phbands.non_anal_phfreqs
Exemplo n.º 2
0
    def run_anaddb(self, dipdip=1):
        print("Run anaddb")
        #os.system('cp ./abinit.mrgddb.tmpl %s/abinit.mrgddb.in' % self.dirname)
        gen_mrgddb_input(self.dirname)
        os.chdir(self.dirname)
        os.system('mrgddb <abinit.mrgddb.in>abinit.mrgddb.log')
        myDDB = DdbFile(filepath='abinit_mrgddb.out', read_blocks=True)

        nqpts = ' '.join(map(str, myDDB._guess_ngqpt()))
        natifc = len(self.atoms)
        atifc = ' '.join([str(i + 1) for i in range(len(self.atoms))])
        dipdip = dipdip

        tdict = {
            'nqpts': nqpts,
            'natifc': natifc,
            'atifc': atifc,
            'dipdip': dipdip
        }

        with open("../abinit_ifc.in.tmpl") as myfile:
            tmpl = string.Template(myfile.read())
        text = tmpl.substitute(tdict)

        os.system('cp ../abinit_ifc.files.tmpl abinit_ifc.files')
        with open('abinit_ifc.in', 'w') as myfile:
            myfile.write(text)
        #os.system('cp ../abinit_ifc.in.tmpl %s/abinit_ifc.in' % self.dirname)
        os.system('anaddb <abinit_ifc.files >abinit_ifc.log')
        os.chdir('../')
Exemplo n.º 3
0
def read_DDB_info(name='LiNbO3'):
    myDDB = DdbFile(filepath='%s/abinit_mrgddb.out' % name, read_blocks=True)
    #print(myDDB._guess_ngqpt())
    #print(myDDB.params)
    qpoints = OrderedDict([('Gamma', (0, 0, 0)), ('X', (0.5, 0, 0)),
                           ('M', (0.5, 0.5, 0)), ('R', (0.5, 0.5, 0.5))])
    #qpoints=OrderedDict()
    #Full phonon band.

    # band without LO-TO

    # band with LO-TO

    # Born effective charge
    emacro, becs = myDDB.anaget_emacro_and_becs()

    #print("")
    #print("Macroscopic dielectric: ", emacro)
    #print("Born effective charges: ", becs)
    # dielectric
    # piezoelectricity
    # Analysis for each Q point.
    for qname in qpoints:
        #print("=============")
        #print("Qpoint: %s: %s" % (qname, qpoints[qname], ))
        #print(myDDB.qindex(qpoints[qname]))
        myphon_bands = myDDB.anaget_phmodes_at_qpoint(qpoint=qpoints[qname],
                                                      workdir=None)
Exemplo n.º 4
0
    def test_read_from_file(self):
        # no becs, so no splitting. The test only checks the parsing
        ddb = DdbFile(os.path.join(test_dir, "ZnO_gamma_becs_DDB"))

        phbands = ddb.anaget_phmodes_at_qpoint(qpoint=[0, 0, 0],
                                               lo_to_splitting=True)

        phbands.non_anal_phfreqs
Exemplo n.º 5
0
    def test_read_from_file(self):
        """Testing non-analytical terms."""
        # no becs, so no splitting. The test only checks the parsing
        with DdbFile(os.path.join(test_dir, "ZnO_gamma_becs_DDB")) as ddb:
            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=[0, 0, 0],
                                                   lo_to_splitting=True)

            assert phbands.amu is not None
            #print(phbands.amu)
            # FIXME: I don't like that we Z as key in amu. Should be the symbol
            self.assert_almost_equal(phbands.amu[30.0], 0.6539e+02)
            self.assert_almost_equal(phbands.amu[8.0], 0.159994e+02)
            self.assert_almost_equal(phbands.amu_symbol["Zn"],
                                     phbands.amu[30.0])
            self.assert_almost_equal(phbands.amu_symbol["O"], phbands.amu[8.0])

            assert phbands.non_anal_ph is not None
            repr(phbands.non_anal_ph)
            str(phbands.non_anal_ph)
            assert phbands.structure == phbands.non_anal_ph.structure
            #assert phbands.non_anal_ph.has_direction(direction=,  cartesian=False)

            # TODO should check numerical values (?)
            assert phbands.non_anal_phfreqs is not None
            assert phbands.non_anal_directions is not None
            assert phbands.non_anal_phdispl_cart is not None
            assert phbands.non_anal_dyn_mat_eigenvect is not None
Exemplo n.º 6
0
def abinp_anaph(options):
    """Build Anaddb input file for the computation of phonon bands DOS."""
    ddb = DdbFile(options.filepath)
    nqsmall = 10
    inp = AnaddbInput.phbands_and_dos(ddb.structure, ddb.guessed_ngqpt, nqsmall, ndivsm=20, q1shft=(0, 0, 0),
        qptbounds=None, asr=2, chneut=0, dipdip=1, dos_method="tetra", lo_to_splitting=False,
        anaddb_args=None, anaddb_kwargs=None)

    return finalize(inp, options)
Exemplo n.º 7
0
    def test_zno_gamma_ddb_with_becs(self):
        """Testing DDB for ZnO: Gamma only, with Born effective charges and E_macro."""
        with DdbFile(os.path.join(test_dir, "ZnO_gamma_becs_DDB")) as ddb:
            repr(ddb)
            str(ddb)
            assert str(ddb.header)
            assert ddb.to_string(verbose=2)
            assert ddb.header["nkpt"] == 486
            assert ddb.header.nband == 22 and ddb.header.occopt == 1
            self.assert_equal(ddb.header.typat, [1, 1, 2, 2])
            assert len(ddb.header.wtk) == ddb.header.nkpt
            #assert ddb.header.occ.shape = (ddb.header.nsppol, ddb.header.nkpt, ddb.header.nsppol)

            assert not ddb.has_qpoint([0.345, 0.456, 0.567])
            assert ddb.has_qpoint([0, 0, 0])
            assert len(ddb.qpoints) == 1
            for qpoint in ddb.qpoints:
                assert ddb.has_qpoint(qpoint)
                assert ddb.has_qpoint(qpoint.frac_coords)
                assert qpoint in ddb.computed_dynmat
                assert len(ddb.computed_dynmat[qpoint].index[0]) == 4

            # Test Lru_cache as well
            assert ddb.has_bec_terms(select="at_least_one")
            assert ddb.has_bec_terms(select="at_least_one")
            assert not ddb.has_bec_terms(select="all")
            assert not ddb.has_bec_terms(select="all")
            assert ddb.has_emacro_terms()
            assert ddb.has_lo_to_data()

            # Get emacro and becs
            emacro, becs = ddb.anaget_emacro_and_becs(chneut=1, verbose=1)
            ref_becs_values = [
                [[2.15646571e+00, 0.00000000e+00, 3.26402110e-25],
                 [0.00000000e+00, 2.15646571e+00, -5.46500204e-24],
                 [-5.66391495e-25, -6.54012564e-25, 2.19362823e+00]],
                [[2.15646571e+00, 0.00000000e+00, 1.19680774e-24],
                 [0.00000000e+00, 2.15646571e+00, 8.10327888e-24],
                 [-1.69917448e-24, -1.30802513e-24, 2.19362823e+00]],
                [[-2.15646571e+00, 6.66133815e-16, -1.84961196e-24],
                 [8.88178420e-16, -2.15646571e+00, 2.82672519e-24],
                 [-3.39834897e-24, -3.27006282e-25, -2.19362823e+00]],
                [[-2.15646571e+00, -6.66133815e-16, 3.26402110e-25],
                 [-8.88178420e-16, -2.15646571e+00, -5.46500204e-24],
                 [5.66391495e-24, 2.28904397e-24, -2.19362823e+00]]
            ]

            self.assert_almost_equal(becs.values, ref_becs_values)
            #self.assert_almost_equal(emacro.values, ref_emacro_values)
            repr(becs)
            str(becs)
            assert becs.to_string(verbose=2)

            # get the dielectric tensor generator from anaddb
            dtg = ddb.anaget_dielectric_tensor_generator(verbose=2)
            assert dtg is not None and hasattr(dtg, "phfreqs")
Exemplo n.º 8
0
    def test_alas_ddb_1qpt_phonons(self):
        """Testing DDB with one q-point"""
        ddb_fname = os.path.join(test_dir, "AlAs_1qpt_DDB")

        with DdbFile(ddb_fname) as ddb:
            print(ddb)
            # Test qpoints.
            assert np.all(ddb.qpoints[0] == [0.25, 0, 0])
            assert len(ddb.qpoints) == 1

            # Test header
            h = ddb.header
            assert h.version == 100401 and h.ecut == 3
            assert "ecut" in h and h["ecut"] == h.ecut
            assert h.occ == 4 * [2]
            assert h.xred.shape == (h.natom, 3) and h.kpt.shape == (h.nkpt, 3)
            print(h.znucl)
            assert "ecut" in ddb.params

            assert np.all(
                h.symrel[1].T.ravel() == [0, -1, 1, 0, -1, 0, 1, -1, 0])
            assert np.all(
                h.symrel[2].T.ravel() == [-1, 0, 0, -1, 0, 1, -1, 1, 0])

            # Test structure
            struct = ddb.structure
            assert struct.formula == "Al1 As1"

            # Test interface with Anaddb.
            print(ddb.qpoints[0])
            assert ddb.qindex(ddb.qpoints[0]) == 0

            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=ddb.qpoints[0],
                                                   verbose=1)
            assert phbands is not None and hasattr(phbands, "phfreqs")

            # Wrong qpoint
            with self.assertRaises(ValueError):
                ddb.anaget_phmodes_at_qpoint(qpoint=(0, 0, 0), verbose=1)

            # Wrong ngqpt
            with self.assertRaises(ddb.AnaddbError):
                ddb.anaget_phbst_and_phdos_files(ngqpt=(4, 4, 4), verbose=1)

            # Cannot compute DOS since we need a mesh.
            with self.assertRaises(ddb.AnaddbError):
                ddb.anaget_phbst_and_phdos_files(verbose=1)

            # Test notebook
            if self.has_nbformat():
                ddb.write_notebook(nbpath=self.get_tmpname(text=True))
Exemplo n.º 9
0
    def run_qlist(self, nqsmall_list, **kwargs):
        """
        """
        self.qha_list = []
        self.ngqpt_list = []

        ddb_list = [DdbFile(p) for p in self.ddb_paths]
        for nqsmall in nqsmall_list:
            phdos_paths = []

            for i, ddb in enumerate(ddb_list):
                phbst_file, phdos_file = ddb.anaget_phbst_and_phdos_files(
                    nqsmall=nqsmall,
                    qppa=None,
                    ndivsm=1,
                    line_density=None,
                    asr=2,
                    chneut=1,
                    dipdip=1,
                    dos_method="tetra",
                    lo_to_splitting="automatic",
                    ngqpt=None,
                    qptbounds=None,
                    anaddb_kwargs=None,
                    verbose=0,
                    spell_check=True,
                    mpi_procs=1,
                    workdir=None,
                    manager=None)

                phdos_paths.append(phdos_file.filepath)
                if i == 0:
                    # These variables added in abinit v8.11. Use nqsmall is not available.
                    ngqpt = 3 * [nqsmall]
                    if "qptrlatt" in phdos_file.reader.rootgrp.variables:
                        ngqpt = np.diagonal(
                            phdos_file.reader.read_value("qptrlatt").T)
                        #shiftq = phdos_file.reader.read_value("shiftq")
                    self.ngqpt_list.append(ngqpt)

                phbst_file.close()
                phdos_file.close()

            qha = QHA.from_files(self.gsr_paths, phdos_paths)
            self.qha_list.append(qha)

        self.ngqpt_list = np.reshape(self.ngqpt_list, (-1, 3))
        self.num_qmeshes = len(self.ngqpt_list)
        for ddb in ddb_list:
            ddb.close()
Exemplo n.º 10
0
    def test_alas_ddb_444_nobecs(self):
        """Testing DDB for AlAs on a 4x4x4x q-mesh without Born effective charges."""
        ddb = DdbFile(os.path.join(test_dir, "AlAs_444_nobecs_DDB"))
        print(ddb)
        print(ddb.header)

        ref_qpoints = np.reshape([
                 0.00000000E+00,  0.00000000E+00,  0.00000000E+00,
                 2.50000000E-01,  0.00000000E+00,  0.00000000E+00,
                 5.00000000E-01,  0.00000000E+00,  0.00000000E+00,
                 2.50000000E-01,  2.50000000E-01,  0.00000000E+00,
                 5.00000000E-01,  2.50000000E-01,  0.00000000E+00,
                -2.50000000E-01,  2.50000000E-01,  0.00000000E+00,
                 5.00000000E-01,  5.00000000E-01,  0.00000000E+00,
                -2.50000000E-01,  5.00000000E-01,  2.50000000E-01,
        ], (-1, 3))

        assert len(ddb.qpoints) == 8
        for qpt, ref_qpt in zip(ddb.qpoints, ref_qpoints):
            assert qpt == ref_qpt

        for qpoint in ddb.qpoints:
            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=qpoint)
            assert phbands is not None and hasattr(phbands, "phfreqs")

        assert np.all(ddb.guessed_ngqpt == [4, 4, 4])

        # Get bands and Dos
        phbands_file, phdos_file = ddb.anaget_phbst_and_phdos_files()
        phbands, phdos = phbands_file.phbands, phdos_file.phdos

        if have_matplotlib:
            phbands.plot_with_phdos(phdos, title="Phonon bands and DOS of %s" % phbands.structure.formula, show=False)

        # Thermodinamics in the Harmonic approximation
        harmo = phdos.get_harmonic_thermo(tstart=10, tstop=50)
        harmo.plot(show=False)

        self.assert_almost_equal(phdos.idos.values[-1], 3 * len(ddb.structure), decimal=1)
        phbands_file.close()
        phdos_file.close()

        c = ddb.anacompare_phdos(nqsmalls=[2, 4, 6], num_cpus=None)
        c.plotter.plot(show=False)

        ddb.close()
Exemplo n.º 11
0
    def from_ddb(cls, ddb, ebands_kpath, ebands_kmesh=None, **kwargs):
        """
        Build the object from the ddb file, invoke anaddb to get phonon properties.
        This entry point is needed to have phonon plots with LO-TO splitting
        as AbiPy will generate an anaddb input with the different q --> 0 directions
        required in phbands.plot to plot the LO-TO splitting correctly.

        Args:
            ddb: |DdbFile| or filepath.
            ebands_kpath: |ElectronBands| with energies on a k-path or filepath.
            ebands_kpath: (optional) |ElectronBands| with energies on a k-mesh or filepath.
            kwargs: Passed to anaget_phbst_and_phdos_files
        """
        ddb = DdbFile.as_ddb(ddb)
        phbst_file, phdos_file = ddb.anaget_phbst_and_phdos_files(**kwargs)
        return cls(ebands_kpath,
                   phbst_file,
                   phdos_file,
                   ebands_kmesh=ebands_kmesh)
Exemplo n.º 12
0
    def test_alas_ddb_444_nobecs(self):
        """Testing DDB for AlAs on a 4x4x4x q-mesh without Born effective charges."""
        ddb = DdbFile(os.path.join(test_dir, "AlAs_444_nobecs_DDB"))
        print(ddb)
        print(ddb.header)

        ref_qpoints = np.reshape([
                 0.00000000E+00,  0.00000000E+00,  0.00000000E+00,
                 2.50000000E-01,  0.00000000E+00,  0.00000000E+00,
                 5.00000000E-01,  0.00000000E+00,  0.00000000E+00,
                 2.50000000E-01,  2.50000000E-01,  0.00000000E+00,
                 5.00000000E-01,  2.50000000E-01,  0.00000000E+00,
                -2.50000000E-01,  2.50000000E-01,  0.00000000E+00,
                 5.00000000E-01,  5.00000000E-01,  0.00000000E+00,
                -2.50000000E-01,  5.00000000E-01,  2.50000000E-01,
        ], (-1, 3))

        assert len(ddb.qpoints) == 8
        for qpt, ref_qpt in zip(ddb.qpoints, ref_qpoints):
            assert qpt == ref_qpt

        for qpoint in ddb.qpoints:
            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=qpoint)
            assert phbands is not None and hasattr(phbands, "phfreqs")

        assert np.all(ddb.guessed_ngqpt == [4, 4, 4])

        # Get bands and Dos
        phbands_file, phdos_file = ddb.anaget_phbst_and_phdos_files()
        phbands, phdos = phbands_file.phbands, phdos_file.phdos

        if self.has_matplotlib():
            phbands.plot_with_phdos(phdos, title="Phonon bands and DOS of %s" % phbands.structure.formula, show=False)

        # Thermodinamics in the Harmonic approximation
        harmo = phdos.get_harmonic_thermo(tstart=10, tstop=50)
        if self.has_matplotlib():
            harmo.plot(show=False)

        self.assert_almost_equal(phdos.idos.values[-1], 3 * len(ddb.structure), decimal=1)
        phbands_file.close()
        phdos_file.close()

        c = ddb.anacompare_phdos(nqsmalls=[2, 4, 6], num_cpus=None)
        if self.has_matplotlib():
            c.plotter.plot(show=False)

        ddb.close()
Exemplo n.º 13
0
def itest_frohlich_zpr_flow(fwp, tvars):
    """
    """
    # Build the SCF input.
    scf_input = make_scf_input()

    # Build the flow.
    from abipy.flowtk.effmass_works import FrohlichZPRFlow
    flow = FrohlichZPRFlow.from_scf_input(fwp.workdir,
                                          scf_input,
                                          ddb_node=None,
                                          ndivsm=2,
                                          tolwfr=1e-10,
                                          manager=fwp.manager,
                                          metadata=dict(mp_id="mp-123"))

    scheduler = flow.make_scheduler()
    assert scheduler.start() == 0
    flow.check_status(show=True)
    assert all(work.finalized for work in flow)
    if not flow.all_ok:
        flow.debug()
        raise RuntimeError()
    assert flow.on_all_ok_num_calls == 1

    # Reconstruct python objects from JSON file.
    data = abilab.mjson_load(flow.outdir.path_in("zprfrohl_results.json"))

    assert data["metadata"]["mp_id"] == "mp-123"
    assert data["structure"].formula == 'Ca1 O1'
    ebands_kpath = data["ebands_kpath"]
    assert ebands_kpath.nsppol == 1
    assert ebands_kpath.kpoints.is_path
    assert ebands_kpath.homos[0].kpoint == [0, 0, 0]
    assert ebands_kpath.lumos[0].kpoint == [0.5, 0, 0.5]
    with DdbFile.from_string(data["ddb_string"]) as ddb:
        assert ddb.structure.formula == 'Ca1 O1'
        assert ddb.has_bec_terms(select="at_least_one")
        assert ddb.has_epsinf_terms(select="at_least_one_diagoterm")
    assert data["epsinf_cart"].shape == data["eps0_cart"].shape
Exemplo n.º 14
0
    def test_alas_ddb_1qpt_phonons(self):
        """Testing DDB with one q-point"""
        with DdbFile(os.path.join(test_dir, "AlAs_1qpt_DDB")) as ddb:
            repr(ddb)
            str(ddb)
            # Test qpoints.
            assert len(ddb.qpoints) == 1
            assert np.all(ddb.qpoints[0] == [0.25, 0, 0])
            assert ddb.natom == len(ddb.structure)
            s = ddb.get_string()
            with DdbFile.from_string(s) as same_ddb:
                assert same_ddb.qpoints[0] == ddb.qpoints[0]
                assert same_ddb.structure == ddb.structure

            # Test header
            h = ddb.header
            assert h.version == 100401 and h.ecut == 3
            assert "ecut" in h and h["ecut"] == h.ecut
            assert "ixc" in ddb.params
            assert ddb.params["ixc"] == 7
            assert h.occ == 4 * [2]
            assert h.xred.shape == (h.natom, 3) and h.kpt.shape == (h.nkpt, 3)
            self.assert_equal(h.znucl, [13, 33])
            assert ddb.version == 100401
            assert ddb.total_energy is None
            assert ddb.cart_forces is None
            assert ddb.cart_stress_tensor is None

            assert np.all(
                h.symrel[1].T.ravel() == [0, -1, 1, 0, -1, 0, 1, -1, 0])
            assert np.all(
                h.symrel[2].T.ravel() == [-1, 0, 0, -1, 0, 1, -1, 1, 0])

            # Test structure
            struct = ddb.structure
            assert struct.formula == "Al1 As1"

            # Test interface with Anaddb.
            str(ddb.qpoints[0])
            assert ddb.qindex(ddb.qpoints[0]) == 0

            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=ddb.qpoints[0],
                                                   verbose=1)
            assert phbands is not None and hasattr(phbands, "phfreqs")
            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=ddb.qpoints[0],
                                                   lo_to_splitting=False,
                                                   verbose=1)

            # Wrong qpoint
            with self.assertRaises(ValueError):
                ddb.anaget_phmodes_at_qpoint(qpoint=(0, 0, 0), verbose=1)

            with self.assertRaises(ValueError):
                ddb.anaget_phmodes_at_qpoints(qpoints=[[0.1, 0.2, 0.3]],
                                              ifcflag=0)

            # Wrong ngqpt
            with self.assertRaises(ddb.AnaddbError):
                try:
                    ddb.anaget_phbst_and_phdos_files(ngqpt=(4, 4, 4),
                                                     verbose=1)
                except Exception as exc:
                    # This to test AnaddbError.__str__
                    str(exc)
                    raise

            # Cannot compute DOS since we need a mesh.
            with self.assertRaises(ddb.AnaddbError):
                ddb.anaget_phbst_and_phdos_files(verbose=1)

            # Test notebook
            if self.has_nbformat():
                assert ddb.write_notebook(nbpath=self.get_tmpname(text=True))

            # Test block parsing.
            blocks = ddb._read_blocks()
            assert len(blocks) == 1
            assert blocks[0]["qpt"] == [0.25, 0, 0]
            assert blocks[0]["dord"] == 2
            assert blocks[0]["qpt3"] == None

            lines = blocks[0]["data"]
            assert lines[0].rstrip(
            ) == " 2nd derivatives (non-stat.)  - # elements :      36"
            assert lines[2].rstrip(
            ) == "   1   1   1   1  0.80977066582497D+01 -0.46347282336361D-16"
            assert lines[-1].rstrip(
            ) == "   3   2   3   2  0.49482344898401D+01 -0.44885664256253D-17"

            for qpt in ddb.qpoints:
                assert ddb.get_block_for_qpoint(qpt)
                assert ddb.get_block_for_qpoint(qpt.frac_coords)

            assert ddb.replace_block_for_qpoint(ddb.qpoints[0],
                                                blocks[0]["data"])
            d_2ord = ddb.get_2nd_ord_dict()
            assert ddb.qpoints[0] in d_2ord
            new_qpt = [0.11, 0.22, 3.4]
            new_block = {
                "data": [
                    ' 2nd derivatives (non-stat.)  - # elements :      1',
                    ' qpt  1.10000000E-01  2.20000000E-01  3.40000000E+00   1.0',
                    '   1   1   1   1  0.38964081001769D+01  0.51387831420710D-24'
                ],
                "dord":
                2,
                "qpt":
                new_qpt,
                "qpt3":
                None
            }
            assert ddb.insert_block(new_block)
            assert ddb.insert_block(new_block, replace=True)
            assert not ddb.insert_block(new_block, replace=False)
            # Write new DDB file.
            tmp_file = self.get_tmpname(text=True)
            ddb.write(tmp_file)
            with DdbFile(tmp_file) as new_ddb:
                # check that the new qpoint has been written to the file
                assert new_qpt in new_ddb.qpoints

            # remove the added block and write again to check that it is equivalent to the original
            assert ddb.remove_block(dord=2, qpt=new_qpt)

            ddb.write(tmp_file)
            with DdbFile(tmp_file) as new_ddb:
                assert ddb.qpoints == new_ddb.qpoints
                assert DdbFile.as_ddb(new_ddb) is new_ddb
                # Call anaddb to check if we can read new DDB
                phbands = new_ddb.anaget_phmodes_at_qpoint(
                    qpoint=new_ddb.qpoints[0], verbose=1)
                assert phbands is not None and hasattr(phbands, "phfreqs")
Exemplo n.º 15
0
    def analyze_all_modes(self):
        self.results = OrderedDict()

        self.results[
            'lattice_parameter'] = self.atoms.get_cell_lengths_and_angles()

        # emacro & BEC
        myDDB = DdbFile(filepath='%s/abinit_mrgddb.out' % (self.dirname),
                        read_blocks=True)

        emacro, becs = myDDB.anaget_emacro_and_becs()
        self.results['dielectric_tensor'] = emacro[0].reduced_tensor
        self.results['Born_effective_charges'] = becs

        self.results['number_of_qpoints'] = myDDB._guess_ngqpt()
        self.results['ecut'] = myDDB.params[u'ecut']
        self.results['tsmear'] = myDDB.params[u'tsmear']
        self.results['nsppol'] = myDDB.params[u'nsppol']
        self.results['nkpt'] = myDDB.params[u'nkpt']

        filefname = os.path.join(self.dirname, 'abinit.files')
        with open(filefname) as myfile:
            self.results['pseudopotentials'] = [
                os.path.split(x)[-1].strip() for x in myfile.readlines()[5:]
            ]

        # Phonon
        self.results['phonon'] = OrderedDict()
        qpoints = OrderedDict([('Gamma', (0, 0, 0)), ('X', (0.5, 0, 0)),
                               ('M', (0.5, 0.5, 0)), ('R', (0.5, 0.5, 0.5))])
        # Phonon: Gamma_reduced
        qname = 'Gamma_reduced'
        self.results['phonon'][qname] = OrderedDict()
        hamk, freqs, evals, evecs, edisps, dc, ds = self.analyze_gamma(
            ibands=None, label='DYM_Gamma_reduced', is_asr=False)
        self.results['phonon'][qname]['dynamic_matrix'] = hamk
        self.results['phonon'][qname]['eigenvalues'] = evals
        self.results['phonon'][qname]['frequencies'] = freqs
        self.results['phonon'][qname]['eigenvectors'] = evecs
        self.results['phonon'][qname]['eigen_displacements'] = edisps
        self.results['phonon'][qname]['dynamic_matrix_contributions'] = dc
        self.results['phonon'][qname]['dynamic_matrix_sensitivities'] = ds

        # Phonon: Other Qpoints
        for qname in qpoints:
            qpoint = qpoints[qname]
            self.results['phonon'][qname] = OrderedDict()
            self.results['phonon'][qname]['qpoint'] = qpoint
            hamk, freqs, evals, evecs, edisps, dc, ds = self.analyze_qpoint(
                qpoint=qpoint, qpt_name=qname, ibands=None)
            self.results['phonon'][qname]['dynamic_matrix'] = hamk
            self.results['phonon'][qname]['eigenvalues'] = evals
            self.results['phonon'][qname]['frequencies'] = freqs
            self.results['phonon'][qname]['eigenvectors'] = evecs
            self.results['phonon'][qname]['eigen_displacements'] = edisps
            self.results['phonon'][qname]['dynamic_matrix_contributions'] = dc
            self.results['phonon'][qname]['dynamic_matrix_sensitivities'] = ds
        #with open('data/%s.json' % (self.dirname), 'w') as myfile:
        #    json.dump(self.results, myfile)
        with open('data/%s.pickle' % (self.dirname), 'wb') as myfile:
            cPickle.dump(self.results, myfile)
        datadir = 'data/%s' % self.dirname
        if not os.path.exists(datadir):
            os.makedirs(datadir)
        os.system('cp %s/*.in %s' % (self.dirname, datadir))
        os.system('cp %s/*.nc %s' % (self.dirname, datadir))
        os.system('cp %s/*DDB %s' % (self.dirname, datadir))
        os.system('cp %s/*.files %s' % (self.dirname, datadir))
        os.system('cp %s/CONTCAR %s' % (self.dirname, datadir))
        os.system('cp %s/*.txt %s' % (self.dirname, datadir))
        os.system('cp %s/*.out %s' % (self.dirname, datadir))
        os.system('tar -zcvf data/%s.tar.gz %s' % (self.dirname, datadir))
Exemplo n.º 16
0
    def test_alas_ddb_444_nobecs(self):
        """Testing DDB for AlAs on a 4x4x4x q-mesh without Born effective charges."""
        ddb = DdbFile(os.path.join(test_dir, "AlAs_444_nobecs_DDB"))
        repr(ddb); str(ddb)
        assert str(ddb.header)
        assert ddb.to_string(verbose=2)
        assert ddb.header["nkpt"] == 256
        assert ddb.header.nsym == 24 and ddb.header.ntypat == 2
        self.assert_equal(ddb.header.znucl, [13, 33])
        self.assert_equal(ddb.header.acell, [1, 1, 1])
        self.assert_equal(ddb.header.ngfft, [10, 10, 10])
        self.assert_equal(ddb.header.spinat, 0.0)
        #assert ddb.header.occ.shape = (ddb.header.nsppol, ddb.header.nkpt, ddb.header.nsppol)

        assert not ddb.has_qpoint([0.345, 0.456, 0.567])
        assert ddb.has_qpoint([0, 0, 0])
        for qpoint in ddb.qpoints:
            assert ddb.has_qpoint(qpoint)
            assert ddb.has_qpoint(qpoint.frac_coords)
            assert qpoint in ddb.computed_dynmat
            assert len(ddb.computed_dynmat[qpoint].index[0]) == 4

        assert ddb.has_bec_terms(select="at_least_one")
        assert not ddb.has_bec_terms(select="all")
        assert not ddb.has_epsinf_terms()
        assert not ddb.has_lo_to_data()
        assert not ddb.has_internalstrain_terms()
        assert not ddb.has_piezoelectric_terms()
        assert not ddb.has_strain_terms()
        assert ddb.has_at_least_one_atomic_perturbation()

        ref_qpoints = np.reshape([
                 0.00000000E+00,  0.00000000E+00,  0.00000000E+00,
                 2.50000000E-01,  0.00000000E+00,  0.00000000E+00,
                 5.00000000E-01,  0.00000000E+00,  0.00000000E+00,
                 2.50000000E-01,  2.50000000E-01,  0.00000000E+00,
                 5.00000000E-01,  2.50000000E-01,  0.00000000E+00,
                -2.50000000E-01,  2.50000000E-01,  0.00000000E+00,
                 5.00000000E-01,  5.00000000E-01,  0.00000000E+00,
                -2.50000000E-01,  5.00000000E-01,  2.50000000E-01,
        ], (-1, 3))

        assert len(ddb.qpoints) == 8
        for qpt, ref_qpt in zip(ddb.qpoints, ref_qpoints):
            assert qpt == ref_qpt

        for qpoint in ddb.qpoints:
            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=qpoint, verbose=1)
            assert phbands is not None and hasattr(phbands, "phfreqs")

        assert np.all(ddb.guessed_ngqpt == [4, 4, 4])

        # Get bands and Dos
        phbands_file, phdos_file = ddb.anaget_phbst_and_phdos_files(verbose=1)
        phbands, phdos = phbands_file.phbands, phdos_file.phdos

        assert ddb.view_phononwebsite(verbose=1, dryrun=True) == 0

        if self.has_matplotlib():
            assert phbands.plot_with_phdos(phdos, show=False,
                title="Phonon bands and DOS of %s" % phbands.structure.formula)
            assert phbands_file.plot_phbands(show=False)

        # Get emacro and becs
        emacro, becs = ddb.anaget_emacro_and_becs(chneut=1, verbose=1)
        assert np.all(becs.values == 0)
        #assert np.all(emacro.values == 0)
        repr(becs); str(becs)
        assert becs.to_string(verbose=2)

        self.assert_almost_equal(phdos.idos.values[-1], 3 * len(ddb.structure), decimal=1)
        phbands_file.close()
        phdos_file.close()

        # Test DOS computation via anaddb.
        c = ddb.anacompare_phdos(nqsmalls=[2, 3, 4], dipdip=0, num_cpus=1, verbose=2)
        assert c.phdoses and c.plotter is not None
        if self.has_matplotlib():
            assert c.plotter.combiplot(show=False)

        # Use threads and gaussian DOS.
        c = ddb.anacompare_phdos(nqsmalls=[2, 3, 4], dos_method="gaussian", dipdip=0, asr=0,
                num_cpus=2, verbose=2)
        assert c.phdoses and c.plotter is not None

        # Execute anaddb to compute the interatomic forces.
        ifc = ddb.anaget_ifc()
        str(ifc); repr(ifc)
        #assert ifc.to_string(verbose=2)
        assert ifc.structure == ddb.structure
        assert ifc.number_of_atoms == len(ddb.structure)

        if self.has_matplotlib():
            assert ifc.plot_longitudinal_ifc(show=False)
            assert ifc.plot_longitudinal_ifc_short_range(show=False)
            assert ifc.plot_longitudinal_ifc_ewald(show=False)

        ddb.close()
Exemplo n.º 17
0
 def setUpClass(cls):
     cls.ddb = DdbFile(os.path.join(test_dir, "AlAs_444_nobecs_DDB"))
     cls.ifc = cls.ddb.anaget_ifc(ifcout=40, ngqpt=[4, 4, 4], verbose=1)
Exemplo n.º 18
0
    def test_zno_gamma_ddb_with_becs(self):
        """Testing DDB for ZnO: Gamma only, with Born effective charges and E_macro."""
        with DdbFile(os.path.join(test_dir, "ZnO_gamma_becs_DDB")) as ddb:
            repr(ddb)
            str(ddb)
            assert str(ddb.header)
            assert ddb.to_string(verbose=2)
            assert ddb.header["nkpt"] == 486
            assert ddb.header.nband == 22 and ddb.header.occopt == 1
            self.assert_equal(ddb.header.typat, [1, 1, 2, 2])
            assert len(ddb.header.wtk) == ddb.header.nkpt
            #assert ddb.header.occ.shape = (ddb.header.nsppol, ddb.header.nkpt, ddb.header.nsppol)

            assert not ddb.has_qpoint([0.345, 0.456, 0.567])
            assert ddb.has_qpoint([0, 0, 0])
            assert len(ddb.qpoints) == 1
            for qpoint in ddb.qpoints:
                assert ddb.has_qpoint(qpoint)
                assert ddb.has_qpoint(qpoint.frac_coords)
                assert qpoint in ddb.computed_dynmat
                assert len(ddb.computed_dynmat[qpoint].index[0]) == 4

            # Test Lru_cache as well
            assert ddb.has_bec_terms(select="at_least_one")
            assert ddb.has_bec_terms(select="at_least_one")
            assert ddb.has_bec_terms(select="all")
            assert ddb.has_bec_terms(select="all")
            assert ddb.has_epsinf_terms()
            assert ddb.has_lo_to_data()

            # Get epsinf and becs
            epsinf, becs = ddb.anaget_epsinf_and_becs(chneut=1, verbose=1)

            ref_becs_values = [
                [[2.15646571e+00, 0.00000000e+00, 3.26402110e-25],
                 [0.00000000e+00, 2.15646571e+00, -5.46500204e-24],
                 [-5.66391495e-25, -6.54012564e-25, 2.19362823e+00]],
                [[2.15646571e+00, 0.00000000e+00, 1.19680774e-24],
                 [0.00000000e+00, 2.15646571e+00, 8.10327888e-24],
                 [-1.69917448e-24, -1.30802513e-24, 2.19362823e+00]],
                [[-2.15646571e+00, 6.66133815e-16, -1.84961196e-24],
                 [8.88178420e-16, -2.15646571e+00, 2.82672519e-24],
                 [-3.39834897e-24, -3.27006282e-25, -2.19362823e+00]],
                [[-2.15646571e+00, -6.66133815e-16, 3.26402110e-25],
                 [-8.88178420e-16, -2.15646571e+00, -5.46500204e-24],
                 [5.66391495e-24, 2.28904397e-24, -2.19362823e+00]]
            ]

            ref_epsinf = [[5.42055574e+00, 8.88178420e-16, -1.30717901e-25],
                          [-8.88178420e-16, 5.42055574e+00, -2.26410045e-25],
                          [-1.30717901e-25, 2.26410045e-25, 4.98835236e+00]]

            self.assert_almost_equal(becs.values, ref_becs_values)
            self.assert_almost_equal(np.array(epsinf), ref_epsinf)
            repr(becs)
            str(becs)
            assert becs.to_string(verbose=2)
            for arr, z in zip(becs.values, becs.zstars):
                self.assert_equal(arr, z)
            df = becs.get_voigt_dataframe(view="all",
                                          select_symbols="O",
                                          verbose=1)
            assert len(df) == 2
            # Equivalent atoms should have same determinant.
            self.assert_almost_equal(df["determinant"].values,
                                     df["determinant"].values[0])

            # get the dielectric tensor generator from anaddb
            dtg = ddb.anaget_dielectric_tensor_generator(verbose=2)
            assert dtg is not None and hasattr(dtg, "phfreqs")
            assert dtg.to_string(verbose=2)
Exemplo n.º 19
0
    def test_alas_ddb_444_nobecs(self):
        """Testing DDB for AlAs on a 4x4x4x q-mesh without Born effective charges."""
        ddb = DdbFile(os.path.join(test_dir, "AlAs_444_nobecs_DDB"))
        repr(ddb)
        str(ddb)
        assert str(ddb.header)
        assert ddb.to_string(verbose=2)
        assert ddb.header["nkpt"] == 256
        assert ddb.header.nsym == 24 and ddb.header.ntypat == 2
        self.assert_equal(ddb.header.znucl, [13, 33])
        self.assert_equal(ddb.header.acell, [1, 1, 1])
        self.assert_equal(ddb.header.ngfft, [10, 10, 10])
        self.assert_equal(ddb.header.spinat, 0.0)
        #assert ddb.header.occ.shape = (ddb.header.nsppol, ddb.header.nkpt, ddb.header.nsppol)

        assert not ddb.has_qpoint([0.345, 0.456, 0.567])
        assert ddb.has_qpoint([0, 0, 0])
        for qpoint in ddb.qpoints:
            assert ddb.has_qpoint(qpoint)
            assert ddb.has_qpoint(qpoint.frac_coords)
            assert qpoint in ddb.computed_dynmat
            assert len(ddb.computed_dynmat[qpoint].index[0]) == 4

        assert ddb.has_bec_terms(select="at_least_one")
        assert not ddb.has_bec_terms(select="all")
        assert not ddb.has_epsinf_terms()
        assert not ddb.has_lo_to_data()
        assert not ddb.has_internalstrain_terms()
        assert not ddb.has_piezoelectric_terms()
        assert not ddb.has_strain_terms()
        assert ddb.has_at_least_one_atomic_perturbation()

        ref_qpoints = np.reshape([
            0.00000000E+00,
            0.00000000E+00,
            0.00000000E+00,
            2.50000000E-01,
            0.00000000E+00,
            0.00000000E+00,
            5.00000000E-01,
            0.00000000E+00,
            0.00000000E+00,
            2.50000000E-01,
            2.50000000E-01,
            0.00000000E+00,
            5.00000000E-01,
            2.50000000E-01,
            0.00000000E+00,
            -2.50000000E-01,
            2.50000000E-01,
            0.00000000E+00,
            5.00000000E-01,
            5.00000000E-01,
            0.00000000E+00,
            -2.50000000E-01,
            5.00000000E-01,
            2.50000000E-01,
        ], (-1, 3))

        assert len(ddb.qpoints) == 8
        for qpt, ref_qpt in zip(ddb.qpoints, ref_qpoints):
            assert qpt == ref_qpt

        for qpoint in ddb.qpoints:
            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=qpoint, verbose=1)
            assert phbands is not None and hasattr(phbands, "phfreqs")

        assert np.all(ddb.guessed_ngqpt == [4, 4, 4])

        # Get bands and Dos
        phbands_file, phdos_file = ddb.anaget_phbst_and_phdos_files(verbose=1)
        phbands, phdos = phbands_file.phbands, phdos_file.phdos

        assert ddb.view_phononwebsite(verbose=1, dryrun=True) == 0

        if self.has_matplotlib():
            assert phbands.plot_with_phdos(phdos,
                                           show=False,
                                           title="Phonon bands and DOS of %s" %
                                           phbands.structure.formula)
            assert phbands_file.plot_phbands(show=False)

        # Get epsinf and becs
        r = ddb.anaget_epsinf_and_becs(chneut=1, verbose=1)
        epsinf, becs = r.epsinf, r.becs
        assert np.all(becs.values == 0)
        repr(becs)
        str(becs)
        assert becs.to_string(verbose=2)

        self.assert_almost_equal(phdos.idos.values[-1],
                                 3 * len(ddb.structure),
                                 decimal=1)
        phbands_file.close()
        phdos_file.close()

        # Test DOS computation via anaddb.
        c = ddb.anacompare_phdos(nqsmalls=[2, 3, 4],
                                 dipdip=0,
                                 num_cpus=1,
                                 verbose=2)
        assert c.phdoses and c.plotter is not None
        if self.has_matplotlib():
            assert c.plotter.combiplot(show=False)

        # Use threads and gaussian DOS.
        c = ddb.anacompare_phdos(nqsmalls=[2, 3, 4],
                                 dos_method="gaussian",
                                 dipdip=0,
                                 asr=0,
                                 num_cpus=2,
                                 verbose=2)
        assert c.phdoses and c.plotter is not None

        # Execute anaddb to compute the interatomic force constants.
        ifc = ddb.anaget_ifc()
        str(ifc)
        repr(ifc)
        assert ifc.to_string(verbose=2)
        assert ifc.structure == ddb.structure
        assert ifc.number_of_atoms == len(ddb.structure)

        if self.has_matplotlib():
            assert ifc.plot_longitudinal_ifc(show=False)
            assert ifc.plot_longitudinal_ifc_short_range(show=False)
            assert ifc.plot_longitudinal_ifc_ewald(show=False)

        # Test get_coarse.
        coarse_ddb = ddb.get_coarse([2, 2, 2])
        # Check whether anaddb can read the coarse DDB.
        coarse_phbands_file, coarse_phdos_file = coarse_ddb.anaget_phbst_and_phdos_files(
            nqsmall=4, ndivsm=1, verbose=1)
        coarse_phbands_file.close()
        coarse_phdos_file.close()
        coarse_ddb.close()

        ddb.close()
Exemplo n.º 20
0
    def test_alas_ddb_444_nobecs(self):
        """Testing DDB for AlAs on a 4x4x4x q-mesh without Born effective charges."""
        ddb = DdbFile(os.path.join(test_dir, "AlAs_444_nobecs_DDB"))
        print(ddb)
        print(ddb.header)

        ref_qpoints = np.reshape([
            0.00000000E+00,
            0.00000000E+00,
            0.00000000E+00,
            2.50000000E-01,
            0.00000000E+00,
            0.00000000E+00,
            5.00000000E-01,
            0.00000000E+00,
            0.00000000E+00,
            2.50000000E-01,
            2.50000000E-01,
            0.00000000E+00,
            5.00000000E-01,
            2.50000000E-01,
            0.00000000E+00,
            -2.50000000E-01,
            2.50000000E-01,
            0.00000000E+00,
            5.00000000E-01,
            5.00000000E-01,
            0.00000000E+00,
            -2.50000000E-01,
            5.00000000E-01,
            2.50000000E-01,
        ], (-1, 3))

        assert len(ddb.qpoints) == 8
        for qpt, ref_qpt in zip(ddb.qpoints, ref_qpoints):
            assert qpt == ref_qpt

        for qpoint in ddb.qpoints:
            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=qpoint, verbose=1)
            assert phbands is not None and hasattr(phbands, "phfreqs")

        assert np.all(ddb.guessed_ngqpt == [4, 4, 4])

        # Get bands and Dos
        phbands_file, phdos_file = ddb.anaget_phbst_and_phdos_files(verbose=1)
        phbands, phdos = phbands_file.phbands, phdos_file.phdos

        if self.has_matplotlib():
            phbands.plot_with_phdos(phdos,
                                    title="Phonon bands and DOS of %s" %
                                    phbands.structure.formula,
                                    show=False)

        # Get emacro and becs
        emacro, becs = ddb.anaget_emacro_and_becs(chneut=1, verbose=1)
        assert np.all(becs.values == 0)
        assert np.all(becs.becs == 0)
        print(becs)

        self.assert_almost_equal(phdos.idos.values[-1],
                                 3 * len(ddb.structure),
                                 decimal=1)
        phbands_file.close()
        phdos_file.close()

        # Test DOS computation via anaddb.
        c = ddb.anacompare_phdos(nqsmalls=[2, 4, 6], num_cpus=None)
        if self.has_matplotlib():
            c.plotter.plot(show=False)

        # Execute anaddb to compute the interatomic forces.
        ifc = ddb.anaget_ifc()
        assert ifc.structure == ddb.structure
        assert ifc.number_of_atoms == len(ddb.structure)

        if self.has_matplotlib():
            ifc.plot_longitudinal_ifc(show=False)
            ifc.plot_longitudinal_ifc_short_range(show=False)
            ifc.plot_longitudinal_ifc_ewald(show=False)

        ddb.close()
Exemplo n.º 21
0
    def test_alas_ddb_1qpt_phonons(self):
        """Testing DDB with one q-point"""
        with DdbFile(os.path.join(test_dir, "AlAs_1qpt_DDB")) as ddb:
            repr(ddb)
            print(ddb)
            # Test qpoints.
            assert len(ddb.qpoints) == 1
            assert np.all(ddb.qpoints[0] == [0.25, 0, 0])
            assert ddb.natom == len(ddb.structure)

            # Test header
            h = ddb.header
            assert h.version == 100401 and h.ecut == 3
            assert "ecut" in h and h["ecut"] == h.ecut
            assert "ixc" in ddb.params
            assert ddb.params["ixc"] == 7
            assert h.occ == 4 * [2]
            assert h.xred.shape == (h.natom, 3) and h.kpt.shape == (h.nkpt, 3)
            self.assert_equal(h.znucl, [13, 33])
            assert ddb.version == 100401
            assert ddb.total_energy is None
            assert ddb.cart_forces is None
            assert ddb.cart_stress_tensor is None

            assert np.all(
                h.symrel[1].T.ravel() == [0, -1, 1, 0, -1, 0, 1, -1, 0])
            assert np.all(
                h.symrel[2].T.ravel() == [-1, 0, 0, -1, 0, 1, -1, 1, 0])

            # Test structure
            struct = ddb.structure
            assert struct.formula == "Al1 As1"

            # Test interface with Anaddb.
            print(ddb.qpoints[0])
            assert ddb.qindex(ddb.qpoints[0]) == 0

            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=ddb.qpoints[0],
                                                   verbose=1)
            assert phbands is not None and hasattr(phbands, "phfreqs")
            phbands = ddb.anaget_phmodes_at_qpoint(qpoint=ddb.qpoints[0],
                                                   lo_to_splitting=False,
                                                   verbose=1)

            # Wrong qpoint
            with self.assertRaises(ValueError):
                ddb.anaget_phmodes_at_qpoint(qpoint=(0, 0, 0), verbose=1)

            # Wrong ngqpt
            with self.assertRaises(ddb.AnaddbError):
                try:
                    ddb.anaget_phbst_and_phdos_files(ngqpt=(4, 4, 4),
                                                     verbose=1)
                except Exception as exc:
                    # This to test AnaddbError.__str__
                    print(exc)
                    raise

            # Cannot compute DOS since we need a mesh.
            with self.assertRaises(ddb.AnaddbError):
                ddb.anaget_phbst_and_phdos_files(verbose=1)

            # Test notebook
            if self.has_nbformat():
                assert ddb.write_notebook(nbpath=self.get_tmpname(text=True))

            # Test block parsing.
            blocks = ddb._read_blocks()
            assert len(blocks) == 1
            assert blocks[0]["qpt"] == [0.25, 0, 0]
            assert blocks[0]["dord"] == 2

            lines = blocks[0]["data"]
            assert lines[0].rstrip(
            ) == " 2nd derivatives (non-stat.)  - # elements :      36"
            assert lines[2].rstrip(
            ) == "   1   1   1   1  0.80977066582497D+01 -0.46347282336361D-16"
            assert lines[-1].rstrip(
            ) == "   3   2   3   2  0.49482344898401D+01 -0.44885664256253D-17"

            for qpt in ddb.qpoints:
                assert ddb.get_block_for_qpoint(qpt)
                assert ddb.get_block_for_qpoint(qpt.frac_coords)

            assert ddb.replace_block_for_qpoint(ddb.qpoints[0],
                                                blocks[0]["data"])

            # Write new DDB file.
            tmp_file = self.get_tmpname(text=True)
            ddb.write(tmp_file)
            with DdbFile(tmp_file) as new_ddb:
                assert ddb.qpoints == new_ddb.qpoints
                assert DdbFile.as_ddb(new_ddb) is new_ddb
                # Call anaddb to check if we can read new DDB
                phbands = new_ddb.anaget_phmodes_at_qpoint(
                    qpoint=new_ddb.qpoints[0], verbose=1)
                assert phbands is not None and hasattr(phbands, "phfreqs")
Exemplo n.º 22
0
def phonopy_to_abinit(unit_cell,
                      supercell_matrix,
                      out_ddb_path,
                      ngqpt=None,
                      qpt_list=None,
                      force_constants=None,
                      force_sets=None,
                      born=None,
                      primitive_matrix="auto",
                      symprec=1e-5,
                      tolsym=None,
                      supercell=None,
                      calculator=None,
                      manager=None,
                      workdir=None,
                      pseudos=None,
                      verbose=False):
    """
    Converts the data from phonopy to an abinit DDB file. The data can be provided
    in form of arrays or paths to the phonopy files that should be parsed.
    The minimal input should contains the FORCE_CONSTANTS or FORCE_SETS.
    If BORN is present the Born effective charges (BEC) and dielectric
    tensor will also be added to the DDB.

    The best agreement is obtained with supercell_matrix and ngqpt being
    equivalent (i.e. supercell_matrix a diagonal matrix with ngqpt as diagonal
    elements). Non diagonal supercell_matrix are allowed as well, but the information
    encoded in the DDB will be the result of an interpolation done through phonopy.

    Phonopy is used to convert the IFC to the dynamical matrix. However, in order to
    determine the list of q-points in the irreducible Brillouin zone and to prepare the
    base for the final DDB file, abinit will be called for a very short and inexpensive run.

    Performs a check to verify if the two codes identify the same symmetries and it gives a
    warning in case of failure. Mismatching symmetries may lead to incorrect conversions.

    Args:
        unit_cell: a |Structure| object that identifies the unit cell used for the phonopy
            calculation.
        supercell_matrix: a 3x3 array representing the supercell matrix used to generated the
            forces with phonopy.
        out_ddb_path: a full path to the file where the new DDB will be written
        ngqpt: a list of 3 elements indicating the grid of q points that will be used in the DDB.
        qpt_list: alternatively to ngqpt an explicit list of q-points can be provided here.
            At least one among ngqpt and qpt_list should be defined.
        force_constants: an array with shape (num atoms unit cell, num atoms supercell, 3, 3)
            containing the force constants. Alternatively a string with the path to the
            FORCE_CONSTANTS file. This or force_set should be defined. If both given this
            has precedence.
        force_sets: a dictionary obtained from the force sets generated with phonopy.
            Alternatively a string with the path to the FORCE_SETS file. This or force_constants
            should be defined.
        born: a dictionary with "dielectric" and "born" keywords as obtained from the nac_params
            in phonopy. Alternatively a string with the path to the BORN file. Notice that
            the "factor" attribute is not taken into account, so the values should be in
            default phonopy units.
        primitive_matrix: a 3x3 array with the primitive matrix passed to Phonopy. "auto" will
            use spglib to try to determine it automatically. If the DDB file should contain the
            actual unit cell this should be the identity matrix.
        symprec: distance tolerance in Cartesian coordinates to find crystal symmetry in phonopy.
            It might be that the value should be tuned so that it leads to the the same symmetries
            as in the abinit calculation.
        tolsym: Gives the tolerance to identify symmetries in abinit. See abinit documentation for
            more details.
        supercell: if given it should represent the supercell used to get the force constants,
            without any perturbation. It will be used to match it to the phonopy supercell
            and sort the IFC in the correct order.
        calculator: a string with the name of the calculator. Will be used to set the conversion
            factor for the force constants coming from phonopy.
        manager: |TaskManager| object. If None, the object is initialized from the configuration file
        pseudos: List of filenames or list of |Pseudo| objects or |PseudoTable| object. It will be
            used by abinit to generate the base DDB file. If None the abipy.data.hgh_pseudos.HGH_TABLE
            table will be used.
        verbose: verbosity level. Set it to a value > 0 to get more information
        workdir: path to the directory where the abinit calculation will be executed.

    Returns:
        a DdbFile instance of the file written in out_ddb_path.
    """

    if ngqpt is None and qpt_list is None:
        raise ValueError(
            "at least one among nqgpt and qpt_list should be defined")

    if force_sets is None and force_constants is None:
        raise ValueError(
            "at least one of force_sets and force_constants should be provided"
        )

    phon_at = get_phonopy_structure(unit_cell)

    if isinstance(force_constants, str):
        force_constants = parse_FORCE_CONSTANTS(filename=force_constants)
    elif force_constants is not None:
        force_constants = np.array(force_constants)
        force_sets = None

    if isinstance(force_sets, str):
        force_sets = parse_FORCE_SETS(filename=force_sets)

    # no nac_params here, otherwise they will be used for the interpolation
    phonon = Phonopy(phon_at,
                     supercell_matrix,
                     primitive_matrix=primitive_matrix,
                     nac_params=None,
                     symprec=symprec,
                     calculator=calculator)

    primitive = get_pmg_structure(phonon.primitive)

    if isinstance(born, str):
        born = parse_BORN(phonon.primitive, filename=born)

    if supercell is not None:
        ph_supercell = get_pmg_structure(phonon.supercell)
        if not np.allclose(supercell.lattice.matrix,
                           ph_supercell.lattice.matrix):
            raise RuntimeError("The lattice of the supercells do not match")
        sc_mapping = []
        for i, site_orig in enumerate(supercell):
            for j, site_ph in enumerate(ph_supercell):
                d = supercell.lattice.get_distance_and_image(
                    site_orig.frac_coords, site_ph.frac_coords)[0]
                if d < 1e-5:
                    sc_mapping.append(j)
                    break
            else:
                raise RuntimeError(
                    f"Could not find a match for site {i} with coords "
                    f"{site_orig.cart_coords} in the supercell.")

        # cross check that the same atom was not matched twice
        n_matches = len(set(sc_mapping))
        if n_matches < len(supercell):
            raise RuntimeError(
                f"Found matches for {n_matches} different atoms in the supercell: {sc_mapping}"
            )

        force_constants = force_constants[:, sc_mapping]

    if force_constants is not None:
        phonon.set_force_constants(force_constants)
    else:
        phonon.dataset = force_sets
        phonon.produce_force_constants()

    if calculator:
        units = get_default_physical_units(calculator)
        fc_factor = get_force_constant_conversion_factor(
            units["force_constants_unit"], None)
        phonon.set_force_constants(phonon.force_constants * fc_factor)

    if pseudos is None:
        from abipy.data.hgh_pseudos import HGH_TABLE
        pseudos = HGH_TABLE

    inp = minimal_scf_input(primitive, pseudos)

    # get the qpoints list if not defined
    if qpt_list is None:
        inp["ngkpt"] = ngqpt
        qpt_list = inp.abiget_ibz(verbose=verbose)[0]

    dm_list = get_dm(phonon, qpt_list, primitive)

    if born is not None:
        # for the conversion of the BEC the zion (i.e. the ionic charge of the pseudo)
        # it is an additive factor and should be the same that goes in the header of the DDB,
        # so take it from the pseudos used to generate it.
        zion = inp.valence_electrons_per_atom
        born_data = generate_born_deriv(born, zion, primitive)
    else:
        born_data = None

    inp = minimal_scf_input(primitive, pseudos)
    if tolsym is not None:
        inp["tolsym"] = tolsym
    task = inp.run_in_shell(workdir=workdir, manager=manager, verbose=verbose)

    # use the output of abinit to check that the spacegroup identified by
    # phonopy and abinit are the same.
    with GsrFile(task.opath_from_ext("GSR.nc")) as gsr:
        abi_spg = gsr.structure.abi_spacegroup.spgid
    spglib_spg = phonon.symmetry.dataset["number"]
    if abi_spg != spglib_spg:
        warnings.warn(
            "The space group number obtained based on the DDB symmetries differs "
            f"from the one calculated with spglib: {abi_spg} versus "
            f"{spglib_spg}. The convertion may be incorrect. Try changing symprec or tolsym."
        )

    tmp_ddb_path = task.opath_from_ext("DDB")

    ddb = DdbFile(tmp_ddb_path)
    # remove the blocks generated by the calculation and that are meaningless
    ddb.remove_block(dord=0)
    ddb.remove_block(dord=1)

    add_data_ddb(ddb, dm_list, qpt_list, born_data)

    ddb.write(out_ddb_path)

    new_ddb = DdbFile(out_ddb_path)
    return new_ddb
Exemplo n.º 23
0
    def from_ddb_list(cls, ddb_list, nqsmall=10, qppa=None, ndivsm=20, line_density=None, asr=2, chneut=1, dipdip=1,
                     dos_method="tetra", lo_to_splitting="automatic", ngqpt=None, qptbounds=None, anaddb_kwargs=None,
                     verbose=0, mpi_procs=1, workdir=None, manager=None):
        """
        Execute anaddb to compute generate the object from a list of ddbs.

        Args:
            ddb_list: A list with the paths to the ddb_files at different volumes. There should be an odd number of
                DDB files and the volume increment must be constant. The DDB files will be ordered according to the
                volume of the unit cell and the middle one will be considered as the DDB at the relaxed volume.
            nqsmall: Defines the homogeneous q-mesh used for the DOS. Gives the number of divisions
                used to sample the smallest lattice vector. If 0, DOS is not computed and
                (phbst, None) is returned.
            qppa: Defines the homogeneous q-mesh used for the DOS in units of q-points per reciprocal atom.
                Overrides nqsmall.
            ndivsm: Number of division used for the smallest segment of the q-path.
            line_density: Defines the a density of k-points per reciprocal atom to plot the phonon dispersion.
                Overrides ndivsm.
            asr, chneut, dipdip: Anaddb input variable. See official documentation.
            dos_method: Technique for DOS computation in  Possible choices: "tetra", "gaussian" or "gaussian:0.001 eV".
                In the later case, the value 0.001 eV is used as gaussian broadening.
            lo_to_splitting: Allowed values are [True, False, "automatic"]. Defaults to "automatic"
                If True the LO-TO splitting will be calculated and the non_anal_directions
                and the non_anal_phfreqs attributes will be addeded to the phonon band structure.
                "automatic" activates LO-TO if the DDB file contains the dielectric tensor and Born effective charges.
            ngqpt: Number of divisions for the q-mesh in the DDB file. Auto-detected if None (default).
            qptbounds: Boundaries of the path. If None, the path is generated from an internal database
                depending on the input structure.
            anaddb_kwargs: additional kwargs for anaddb.
            verbose: verbosity level. Set it to a value > 0 to get more information.
            mpi_procs: Number of MPI processes to use.
            workdir: Working directory. If None, a temporary directory is created.
            manager: |TaskManager| object. If None, the object is initialized from the configuration file.

        Returns:
            A GrunsNcFile object.
        """

        if len(ddb_list) % 2 != 1:
            raise ValueError("An odd number of ddb file paths should be provided")

        ddbs = [DdbFile(d) for d in ddb_list]
        ddbs = sorted(ddbs, key=lambda d: d.structure.volume)
        iv0 = int((len(ddbs) - 1) / 2)
        ddb0 = ddbs[iv0]
        # update list of paths with absolute paths in the correct order
        ddb_list = [d.filepath for d in ddbs]

        if ngqpt is None: ngqpt = ddb0.guessed_ngqpt

        if lo_to_splitting == "automatic":
            lo_to_splitting = ddb0.has_lo_to_data() and dipdip != 0

        if lo_to_splitting and not ddb0.has_lo_to_data():
            cprint("lo_to_splitting is True but Emacro and Becs are not available in DDB: %s" % ddb0.filepath, "yellow")

        inp = AnaddbInput.phbands_and_dos(
            ddb0.structure, ngqpt=ngqpt, ndivsm=ndivsm, nqsmall=nqsmall, qppa=qppa, line_density=line_density,
            q1shft=(0, 0, 0), qptbounds=qptbounds, asr=asr, chneut=chneut, dipdip=dipdip, dos_method=dos_method,
            lo_to_splitting=lo_to_splitting, anaddb_kwargs=anaddb_kwargs)

        inp["gruns_ddbs"] = ['"'+p+'"\n' for p in ddb_list]
        inp["gruns_nddbs"] = len(ddb_list)

        task = AnaddbTask.temp_shell_task(inp, ddb_node=ddb0.filepath, workdir=workdir, manager=manager, mpi_procs=mpi_procs)

        if verbose:
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here.
        task.start_and_wait(autoparal=False)

        report = task.get_event_report()
        if not report.run_completed:
            raise ddb0.AnaddbError(task=task, report=report)

        gruns = cls.from_file(os.path.join(task.workdir, "run.abo_GRUNS.nc"))

        return gruns
Exemplo n.º 24
0
    def from_ddb(cls,
                 ddb_path,
                 directions=None,
                 labels=None,
                 num_points=20,
                 qpt_norm=0.1,
                 ignore_neg_freqs=True,
                 asr=2,
                 chneut=1,
                 dipdip=1,
                 ngqpt=None,
                 spell_check=True,
                 anaddb_kwargs=None,
                 verbose=0,
                 mpi_procs=1,
                 workdir=None,
                 manager=None):
        """
        Creates and instance of the object. Runs anaddb along the specified
        directions or the standard directions in the standard paths given
        in :cite:`Setyawan2010`. The values of the speed of sound
        will be calculated as the slope of the linear fits along each direction.

        Args:
            ddb_path (str): path to the ddb file.
            directions (list): list of qpoints identifying the directions for the calculation
                of the speed of sound. In fractional coordinates.
            labels (list): list of string with the name of the directions.
            num_points (int): number of points calculated along each direction and used to
                fit the speed of sound.
            qpt_norm (float): Norm of the largest point in fractional coordinates for
                each of the directions considered.
            ignore_neg_freqs (bool): if True points with negative frequencies will not be
                considered in the fit, in order to ignore inaccuracies in the long range
                behavior.
            asr, chneut, dipdip: Anaddb input variable. See official documentation.
            ngqpt: Number of divisions for the q-mesh in the DDB file. Auto-detected if None (default).
            anaddb_kwargs: additional kwargs for anaddb.
            verbose: verbosity level. Set it to a value > 0 to get more information.
            mpi_procs: Number of MPI processes to use.
            workdir: Working directory. If None, a temporary directory is created.
            manager: |TaskManager| object. If None, the object is initialized from the configuration file.
        long.

        Returns:
            an instance of SoundVelocity
        """
        with DdbFile(ddb_path) as ddb:
            if ngqpt is None: ngqpt = ddb.guessed_ngqpt

            inp = AnaddbInput(ddb.structure,
                              comment="ANADDB input for speed of sound",
                              anaddb_kwargs=anaddb_kwargs,
                              spell_check=spell_check)

            q1shft = [[0, 0, 0]]
            inp.set_vars(
                ifcflag=1,
                ngqpt=np.array(ngqpt),
                q1shft=q1shft,
                nqshft=len(q1shft),
                asr=asr,
                chneut=chneut,
                dipdip=dipdip,
            )

            if not directions:
                hs = ddb.structure.hsym_kpath
                kpath = hs.kpath

                directions = []
                labels = []

                for chunk in kpath["path"]:
                    for i, q in enumerate(chunk):
                        if "Gamma" in q:
                            if i > 0 and q not in labels:
                                new_q = kpath["kpoints"][chunk[i - 1]]
                                directions.append(new_q)
                                labels.append(chunk[i - 1])
                            if i < len(chunk) - 1 and q not in labels:
                                new_q = kpath["kpoints"][chunk[i + 1]]
                                directions.append(new_q)
                                labels.append(chunk[i + 1])

            qpts = []
            for q in directions:
                q = qpt_norm * q / np.linalg.norm(q)
                steps = q / num_points
                qpts.extend((steps[:, None] * np.arange(num_points)).T)

            n_qpoints = len(qpts)
            qph1l = np.zeros((n_qpoints, 4))

            qph1l[:, :-1] = qpts
            qph1l[:, -1] = 1

            inp['qph1l'] = qph1l.tolist()
            inp['nph1l'] = n_qpoints

            task = ddb._run_anaddb_task(inp,
                                        mpi_procs=mpi_procs,
                                        workdir=workdir,
                                        manager=manager,
                                        verbose=verbose)

            phbst_path = os.path.join(task.workdir, "run.abo_PHBST.nc")

            return cls.from_phbst(phbst_path,
                                  ignore_neg_freqs=ignore_neg_freqs,
                                  labels=labels)