Esempio n. 1
0
 def test_convert_to_ieee(self):
     for entry in self.ieee_data:
         xtal = entry["xtal"]
         struct = entry["structure"]
         orig = Tensor(entry["original_tensor"])
         ieee = Tensor(entry["ieee_tensor"])
         diff = np.max(abs(ieee - orig.convert_to_ieee(struct)))
         err_msg = f"{xtal} IEEE conversion failed with max diff {diff}. Numpy version: {np.__version__}"
         converted = orig.convert_to_ieee(struct, refine_rotation=False)
         self.assertArrayAlmostEqual(ieee,
                                     converted,
                                     err_msg=err_msg,
                                     decimal=3)
         converted_refined = orig.convert_to_ieee(struct,
                                                  refine_rotation=True)
         err_msg = "{} IEEE conversion with refinement failed with max diff {}. Numpy version: {}".format(
             xtal, diff, np.__version__)
         self.assertArrayAlmostEqual(ieee,
                                     converted_refined,
                                     err_msg=err_msg,
                                     decimal=2)
Esempio n. 2
0
    def calc(self, item):
        """
        Process the tasks and materials into a dielectrics collection

        Args:
            item dict: a dict of material_id, structure, and tasks

        Returns:
            dict: a dieletrics dictionary
        """
        def poly(matrix):
            diags = np.diagonal(matrix)
            return np.prod(diags) / np.sum(
                np.prod(comb) for comb in combinations(diags, 2))

        if item["bandstructure"]["band_gap"] > 0:

            structure = Structure.from_dict(
                item.get("dielectric", {}).get("structure", None))

            ionic = Tensor(
                item["dielectric"]["ionic"]).convert_to_ieee(structure)
            static = Tensor(
                item["dielectric"]["static"]).convert_to_ieee(structure)
            total = ionic + static

            d = {
                "dielectric": {
                    "total": total,
                    "ionic": ionic,
                    "static": static,
                    "e_total": np.average(np.diagonal(total)),
                    "e_ionic": np.average(np.diagonal(ionic)),
                    "e_static": np.average(np.diagonal(static)),
                    "n": np.sqrt(np.average(np.diagonal(static))),
                }
            }

            sga = SpacegroupAnalyzer(structure)
            # Update piezo if non_centrosymmetric
            if item.get("piezo", False) and not sga.is_laue():
                static = PiezoTensor.from_voigt(
                    np.array(item["piezo"]["static"]))
                ionic = PiezoTensor.from_voigt(np.array(
                    item["piezo"]["ionic"]))
                total = ionic + static

                # Symmeterize Convert to IEEE orientation
                total = total.convert_to_ieee(structure)
                ionic = ionic.convert_to_ieee(structure)
                static = static.convert_to_ieee(structure)

                directions, charges, strains = np.linalg.svd(
                    total.voigt, full_matrices=False)

                max_index = np.argmax(np.abs(charges))

                max_direction = directions[max_index]

                # Allow a max miller index of 10
                min_val = np.abs(max_direction)
                min_val = min_val[min_val > (np.max(min_val) /
                                             self.max_miller)]
                min_val = np.min(min_val)

                d["piezo"] = {
                    "total": total.zeroed().voigt,
                    "ionic": ionic.zeroed().voigt,
                    "static": static.zeroed().voigt,
                    "e_ij_max": charges[max_index],
                    "max_direction": np.round(max_direction / min_val),
                    "strain_for_max": strains[max_index],
                }
        else:
            d = {
                "dielectric": {},
                "_warnings": [
                    "Dielectric calculated for likely metal. Values are unlikely to be converged"
                ],
            }

            if item.get("piezo", False):
                d.update({
                    "piezo": {},
                    "_warnings": [
                        "Piezoelectric calculated for likely metal. Values are unlikely to be converged"
                    ],
                })

        return d