コード例 #1
0
 def test_init(self):
     test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "test_files")
     analysis = BaderAnalysis(os.path.join(test_dir, "CHGCAR.Fe3O4"), os.path.join(test_dir, "POTCAR.Fe3O4"))
     self.assertEqual(len(analysis.data), 14)
     self.assertAlmostEqual(analysis.data[0]["charge"], 6.1485)
     self.assertAlmostEqual(analysis.nelectrons, 96)
     self.assertAlmostEqual(analysis.vacuum_charge, 0)
     ans = [
         -1.8515,
         -1.8132,
         -1.8132,
         -1.5562,
         -1.8132,
         -1.8515,
         1.3369,
         1.3378,
         1.3373,
         1.3374,
         1.3374,
         1.3369,
         1.3373,
         1.3378,
     ]
     for i in range(14):
         self.assertAlmostEqual(ans[i], analysis.get_charge_transfer(i))
     s = analysis.get_oxidation_state_decorated_structure()
     self.assertAlmostEqual(s[0].specie.oxi_state, -1.8515)
コード例 #2
0
 def test_from_path(self):
     test_dir = os.path.join(PymatgenTest.TEST_FILES_DIR, "bader")
     analysis = BaderAnalysis.from_path(test_dir)
     chgcar = os.path.join(test_dir, "CHGCAR.gz")
     chgref = os.path.join(test_dir, "_CHGCAR_sum.gz")
     analysis0 = BaderAnalysis(chgcar_filename=chgcar,
                               chgref_filename=chgref)
     charge = np.array(analysis.summary["charge"])
     charge0 = np.array(analysis0.summary["charge"])
     self.assertTrue(np.allclose(charge, charge0))
     if os.path.exists("CHGREF"):
         os.remove("CHGREF")
コード例 #3
0
 def test_init(self):
     test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..",
                             'test_files')
     analysis = BaderAnalysis(os.path.join(test_dir, "CHGCAR.Fe3O4"),
                              os.path.join(test_dir, "POTCAR.Fe3O4"))
     self.assertEqual(len(analysis.data), 14)
     self.assertAlmostEqual(analysis.data[0]["charge"], 6.1485)
     self.assertAlmostEqual(analysis.nelectrons, 96)
     self.assertAlmostEqual(analysis.vacuum_charge, 0)
     ans = [-1.8515, -1.8132, -1.8132, -1.5562, -1.8132, -1.8515, 1.3369,
            1.3378, 1.3373, 1.3374, 1.3374, 1.3369, 1.3373, 1.3378]
     for i in range(14):
         self.assertAlmostEqual(ans[i], analysis.get_charge_transfer(i))
コード例 #4
0
    def test_atom_parsing(self):
        # test with reference file
        analysis = BaderAnalysis(
            chgcar_filename=os.path.join(PymatgenTest.TEST_FILES_DIR,
                                         "CHGCAR.Fe3O4"),
            potcar_filename=os.path.join(PymatgenTest.TEST_FILES_DIR,
                                         "POTCAR.Fe3O4"),
            chgref_filename=os.path.join(PymatgenTest.TEST_FILES_DIR,
                                         "CHGCAR.Fe3O4_ref"),
            parse_atomic_densities=True,
        )

        self.assertEqual(len(analysis.atomic_densities),
                         len(analysis.chgcar.structure))

        self.assertAlmostEqual(
            np.sum(analysis.chgcar.data["total"]),
            np.sum([np.sum(d["data"]) for d in analysis.atomic_densities]),
        )
コード例 #5
0
ファイル: charges.py プロジェクト: gmatteo/abipy
    def from_files(cls, density_path, pseudopotential_paths, with_core=True, workdir=None, **kwargs):
        """
        Uses the abinit density files and the bader_ executable from Henkelmann et al. to calculate
        the bader charges of the system. If pseudopotentials are given, the atomic charges will be
        extracted as well. See also :cite:`Henkelman2006`.

        The extraction of the core charges may be a time consuming calculation, depending on the
        size of the system. A tuning of the parameters may be required (see Density.ae_core_density_on_mesh).

        Args:
            density_path: Path to the abinit density file. Can be a fortran _DEN or a netCDF DEN.nc file.
                In case of fortran file, requires cut3d (version >= 8.6.1) for the convertion.
            pseudopotential_paths: Dictionary {element: pseudopotential path} for all the elements present
                in the system.
            with_core: Core charges will be extracted from the pseudopotentials with the
                Density.ae_core_density_on_mesh method. Requires pseudopotential_paths.
            workdir: Working directory. If None, a temporary directory is created.
            kwargs: arguments passed to the method ``Density.ae_core_density_on_mesh``

        Returns:
            An instance of :class:`BaderCharges`
        """
        # read the valence density
        # if density is not a netcdf file, convert with cut3d
        if not density_path.endswith('.nc'):
            dff = DensityFortranFile.from_file(density_path)
            density = dff.get_density()
        else:
            density = Density.from_file(density_path)

        structure = density.structure

        atomic_charges = None

        if with_core:
            if not pseudopotential_paths:
                raise ValueError("pseudopotentials should be provided to extract the core densities")

            try:
                from pseudo_dojo.ppcodes.oncvpsp import psp8_get_densities
            except ImportError as exc:
                print("PseudoDojo package required to extract core densities. "
                      "Please install it with `pip install pseudo_dojo`")
                raise exc

            # extract core charge from pseudopotentials on a radial grid in the correct units
            rhoc = {}
            for specie, ppath in pseudopotential_paths.items():
                r = psp8_get_densities(ppath)
                rhoc[specie] = [r.rmesh * bohr_to_angstrom, r.aecore / (4.0 * np.pi) / (bohr_to_angstrom ** 3)]

            workdir = tempfile.mkdtemp() if workdir is None else workdir

            # extrapolate the core density on the density grid
            core_density = Density.ae_core_density_on_mesh(density, structure, rhoc, **kwargs)
            density += core_density
            atomic_charges = [s.specie.Z for s in structure]

        elif pseudopotential_paths:
            pseudos = {k: Pseudo.from_file(p) for k, p in pseudopotential_paths.items()}
            atomic_charges = [pseudos[s.specie.name].Z_val for s in structure]

        chgcar_path = os.path.join(workdir, 'CHGCAR')
        density.to_chgcar(chgcar_path)

        ba = BaderAnalysis(chgcar_path)

        charges = [ba.get_charge(i) for i in range(len(structure))]

        return cls(charges, structure, atomic_charges)
コード例 #6
0
    def test_init(self):
        # test with reference file
        analysis = BaderAnalysis(
            chgcar_filename=os.path.join(PymatgenTest.TEST_FILES_DIR,
                                         "CHGCAR.Fe3O4"),
            potcar_filename=os.path.join(PymatgenTest.TEST_FILES_DIR,
                                         "POTCAR.Fe3O4"),
            chgref_filename=os.path.join(PymatgenTest.TEST_FILES_DIR,
                                         "CHGCAR.Fe3O4_ref"),
        )
        self.assertEqual(len(analysis.data), 14)
        self.assertAlmostEqual(analysis.data[0]["charge"], 6.6136782, 3)
        self.assertEqual(analysis.data[0]["charge"], analysis.get_charge(0))
        self.assertAlmostEqual(analysis.nelectrons, 96)
        self.assertAlmostEqual(analysis.vacuum_charge, 0)
        ans = [
            -1.3863218,
            -1.3812175,
            -1.3812175,
            -1.2615902,
            -1.3812175,
            -1.3862971,
            1.021523,
            1.024357,
            1.021523,
            1.021523,
            1.021523,
            1.021523,
            1.021523,
            1.024357,
        ]
        for i in range(14):
            self.assertAlmostEqual(ans[i], analysis.get_charge_transfer(i), 3)
        self.assertEqual(analysis.get_partial_charge(0),
                         -analysis.get_charge_transfer(0))
        s = analysis.get_oxidation_state_decorated_structure()
        self.assertAlmostEqual(s[0].specie.oxi_state, 1.3863218, 3)

        # make sure bader still runs without reference file
        analysis = BaderAnalysis(chgcar_filename=os.path.join(
            PymatgenTest.TEST_FILES_DIR, "CHGCAR.Fe3O4"))
        self.assertEqual(len(analysis.data), 14)

        # Test Cube file format parsing
        analysis = BaderAnalysis(cube_filename=os.path.join(
            PymatgenTest.TEST_FILES_DIR, "bader/elec.cube.gz"))
        self.assertEqual(len(analysis.data), 9)
コード例 #7
0
ファイル: charges.py プロジェクト: xue-smile/abipy
    def from_files(cls, density_path, pseudopotential_paths, with_core=True, workdir=None, **kwargs):
        """
        Uses the abinit density files and the bader_ executable from Henkelmann et al. to calculate
        the bader charges of the system. If pseudopotentials are given, the atomic charges will be
        extracted as well. See also :cite:`Henkelman2006`.

        The extraction of the core charges may be a time consuming calculation, depending on the
        size of the system. A tuning of the parameters may be required (see Density.ae_core_density_on_mesh).

        Args:
            density_path: Path to the abinit density file. Can be a fortran _DEN or a netCDF DEN.nc file.
                In case of fortran file, requires cut3d (version >= 8.6.1) for the convertion.
            pseudopotential_paths: Dictionary {element: pseudopotential path} for all the elements present
                in the system.
            with_core: Core charges will be extracted from the pseudopotentials with the
                Density.ae_core_density_on_mesh method. Requires pseudopotential_paths.
            workdir: Working directory. If None, a temporary directory is created.
            kwargs: arguments passed to the method ``Density.ae_core_density_on_mesh``

        Returns:
            An instance of :class:`BaderCharges`
        """
        # read the valence density
        # if density is not a netcdf file, convert with cut3d
        if not density_path.endswith('.nc'):
            dff = DensityFortranFile.from_file(density_path)
            density = dff.get_density()
        else:
            density = Density.from_file(density_path)

        structure = density.structure

        atomic_charges = None

        if with_core:
            if not pseudopotential_paths:
                raise ValueError("pseudopotentials should be provided to extract the core densities")

            try:
                from pseudo_dojo.ppcodes.oncvpsp import psp8_get_densities
            except ImportError as exc:
                print("PseudoDojo package required to extract core densities. "
                      "Please install it with `pip install pseudo_dojo`")
                raise exc

            # extract core charge from pseudopotentials on a radial grid in the correct units
            rhoc = {}
            for specie, ppath in pseudopotential_paths.items():
                r = psp8_get_densities(ppath)
                rhoc[specie] = [r.rmesh * bohr_to_angstrom, r.aecore / (4.0 * np.pi) / (bohr_to_angstrom ** 3)]

            workdir = tempfile.mkdtemp() if workdir is None else workdir

            # extrapolate the core density on the density grid
            core_density = Density.ae_core_density_on_mesh(density, structure, rhoc, **kwargs)
            density += core_density
            atomic_charges = [s.specie.Z for s in structure]

        elif pseudopotential_paths:
            pseudos = {k: Pseudo.from_file(p) for k, p in pseudopotential_paths.items()}
            atomic_charges = [pseudos[s.specie.name].Z_val for s in structure]

        chgcar_path = os.path.join(workdir, 'CHGCAR')
        density.to_chgcar(chgcar_path)

        ba = BaderAnalysis(chgcar_path)

        charges = [ba.get_charge(i) for i in range(len(structure))]

        return cls(charges, structure, atomic_charges)
コード例 #8
0
ファイル: baderana.py プロジェクト: caer200/ocelot_api
These two charge density files can be summed using the chgsum.pl script:

  chgsum.pl AECCAR0 AECCAR2

The total charge will be written to CHGCAR_sum.

The bader analysis can then be done on this total charge density file:

  bader CHGCAR -ref CHGCAR_sum

One finally note is that you need a fine fft grid to accurately reproduce the correct total core charge. 
It is essential to do a few calculations, increasing NG(X,Y,Z)F until the total charge is correct. 
"""

ba = BaderAnalysis(
    'CHGCAR',
    'POTCAR')  # this is a good example for running code and capturing stdout
# print(ba.get_charge(1))

from ocelot.routines.pbc import PBCparser
from pymatgen.core.structure import Structure

struct = Structure.from_file('CONTCAR')
mols, unwrap_str_sorted, unwrap_pblock_list = PBCparser.unwrap(struct)


def parse_acf(acfdata_fn='./ACF.dat'):
    acfdata = []
    with open(acfdata_fn, 'r') as f:
        ls = f.readlines()
    for l in ls[2:-4]: