Beispiel #1
0
    def test_dos_construction_from_frequencies(self):
        """ Test that we can make sensible phonon DOS's and free
        energy calculations from frequency and qpoint data, and that
        it agrees with CASTEP's calculated values.

        """

        fname = REAL_PATH + "data/castep_files/CuP-thermo-test.castep"
        doc, _ = castep2dict(fname, db=False)
        dos = VibrationalDOS(doc)
        backup_eigs = np.copy(dos.eigs)
        self.assertAlmostEqual(dos.zpe,
                               doc["thermo_zero_point_energy"] /
                               doc["num_atoms"],
                               places=4)
        np.testing.assert_array_equal(
            dos.eigs,
            backup_eigs,
            err_msg="Eigenvalues were changed by some function")
        self.assertAlmostEqual(
            dos.vibrational_free_energy(1000),
            doc["thermo_free_energy"][1000.0] / doc["num_atoms"],
            places=4,
        )
        np.testing.assert_array_equal(
            dos.eigs,
            backup_eigs,
            err_msg="Eigenvalues were changed by some function")
        self.assertEqual(dos.compute_free_energy(0.0), dos.zpe)
Beispiel #2
0
    def test_failed_make_from_castep(self):
        """ Tests that an error is raised when trying to create
        a Spectral object from a castep file that contains no
        spectral data.

        """
        fname = REAL_PATH + "data/castep_files/KP-castep17.castep"
        doc, s = castep2dict(fname, db=False)

        with self.assertRaises(RuntimeError):
            ElectronicDispersion(doc)

        with self.assertRaises(RuntimeError):
            ElectronicDispersion(**doc)

        with self.assertRaises(RuntimeError):
            ElectronicDOS(doc)

        with self.assertRaises(RuntimeError):
            ElectronicDOS(**doc)

        with self.assertRaises(RuntimeError):
            VibrationalDOS(doc)

        with self.assertRaises(RuntimeError):
            VibrationalDOS(**doc)

        with self.assertRaises(RuntimeError):
            VibrationalDispersion(doc)

        with self.assertRaises(RuntimeError):
            VibrationalDispersion(**doc)
Beispiel #3
0
    def test_td_hull_plot(self):
        from matador.hull.hull_temperature import TemperatureDependentHull
        from matador.scrapers import castep2dict

        cursor, s = castep2dict(REAL_PATH +
                                "data/castep_phonon_files/*.castep",
                                db=False)
        td_hull = TemperatureDependentHull(cursor=cursor,
                                           energy_key="total_energy_per_atom")
        td_hull.plot_hull(plot_fname="td_hull", png=True)
        self.assertTrue(os.path.isfile("td_hull.png"))
Beispiel #4
0
    def test_doc2pmg(self):
        from matador.scrapers import castep2dict

        doc, s = castep2dict(REAL_PATH +
                             "data/castep_files/KP-castep17.castep",
                             as_model=True)

        pmg_structure = doc.pmg_structure
        self.assertEqual(pmg_structure.formula, "K7 P2")
        np.testing.assert_array_almost_equal(pmg_structure.lattice.matrix,
                                             doc.lattice_cart,
                                             decimal=16)
        for ind, site in enumerate(doc):
            np.testing.assert_array_almost_equal(
                site.coords, pmg_structure[ind].frac_coords, decimal=16)
            self.assertEqual(site.species, pmg_structure[ind].species_string)

        self.assertDictEqual(pmg_structure.info["matador"], doc._data)
Beispiel #5
0
    def test_beef_hull_plot(self):
        """ Test plotting BEEF hull. """
        from matador.hull import EnsembleHull
        from matador.scrapers import castep2dict

        expected_file = "KP_beef_hull.svg"
        cursor, s = castep2dict(REAL_PATH + "data/beef_files/*.castep",
                                db=False)
        self.assertEqual(len(s), 0)

        beef_hull = EnsembleHull(
            cursor,
            "_beef",
            elements=["K", "P"],
            num_samples=10,
            energy_key="total_energy_per_atom",
            parameter_key="thetas",
        )

        beef_hull.plot_hull(svg=True)
        self.assertTrue(os.path.isfile(expected_file))
Beispiel #6
0
    def test_doc2ase(self):
        from matador.scrapers import castep2dict

        doc, s = castep2dict(REAL_PATH +
                             "data/castep_files/KP-castep17.castep",
                             as_model=True)

        ase_atoms = doc.ase_atoms
        np.testing.assert_array_almost_equal(ase_atoms.cell.array,
                                             doc.lattice_cart,
                                             decimal=16)

        np.testing.assert_array_almost_equal(doc.positions_frac,
                                             ase_atoms.get_scaled_positions(),
                                             decimal=12)

        for ind, site in enumerate(doc):
            np.testing.assert_array_almost_equal(site.coords_cartesian,
                                                 ase_atoms[ind].position,
                                                 decimal=12)
            self.assertEqual(site.species, ase_atoms[ind].symbol)

        self.assertDictEqual(ase_atoms.info["matador"], doc._data)
Beispiel #7
0
def get_equation_of_state(seed, plot=False):
    """ Extract E(V) data from CASTEP files and perform
    fits for the equation of state and bulk moduli.

    Parameters:
        seed (str/dict): filename or scraped dictionary to fit.

    Keyword arguments:
        plot (bool): plot the fitted EoS.

    """
    if isinstance(seed, dict):
        results = seed
    else:
        from matador.scrapers import castep2dict
        results, success = castep2dict(seed, intermediates=True, db=False)
        if not success:
            raise RuntimeError(results)

    volumes = []
    energies = []
    for snapshot in results['intermediates']:
        volumes.append(snapshot['cell_volume'])
        energies.append(snapshot['total_energy'])
    volumes.append(results['cell_volume'])
    energies.append(results['total_energy'])
    volumes = np.asarray(volumes)
    energies = np.asarray(energies)

    if len(volumes) < 3:
        raise RuntimeError('Seed {} does not contain enough energies vs volumes to fit a bulk modulus')

    energies = energies[np.argsort(volumes)]
    volumes = np.sort(volumes)

    E_0 = np.min(energies)
    V_0 = volumes[np.argmin(energies)]

    types_of_fit = EquationOfState.__subclasses__()

    results['eos'] = []
    results['summary'] = []
    probes_all = []
    curves = []
    labels = []

    for eos_type in types_of_fit:
        eos = eos_type(E_0, V_0)
        eos.fit(volumes, energies)

        results['summary'].append(eos_type.__name__ + '\n')
        results['summary'].append('fitting parameters = {d[0]:.6f}, {d[1]:.6f}\n'.format(d=eos.fit_parameters))
        results['summary'].append('rrrmsd = {:10.10f} %\n'.format(eos.rrmsd))
        results['summary'].append('bulk modulus = {d[0]:.6f} +/- {d[1]:.6f} GPa\n'
                                  .format(d=(eos.bulk_modulus, eos.bulk_modulus_err)))
        results['summary'].append(80*'-' + '\n')
        probes = np.linspace(min(volumes), max(volumes), num=100)
        fitted_curve = eos.evaluate(probes, *eos.popt)
        results['eos'].append(eos)
        probes_all.append(probes)
        curves.append(fitted_curve)
        name = eos_type.__name__.replace('EOS', '')
        label = '-'.join(re.findall('[A-Z][^A-Z]*', name))
        label += " {eos.bulk_modulus:3.1f}±{eos.bulk_modulus_err:3.1f} GPa"
        labels.append(label)

    if plot:
        try:
            plot_volume_curve(probes_all, labels, curves, volumes, energies, seed)
        except Exception:
            print("There was a problem making the bulk modulus plot.")

    return results