Beispiel #1
0
 def test_from_voigt(self):
     with self.assertRaises(ValueError):
         ElasticTensor.from_voigt([[59.33, 28.08, 28.08, 0],
                                   [28.08, 59.31, 28.07, 0],
                                   [28.08, 28.07, 59.32, 0, 0],
                                   [0, 0, 0, 26.35, 0],
                                   [0, 0, 0, 0, 26.35]])
     with warnings.catch_warnings(record=True) as w:
         ElasticTensor.from_voigt([[59.33, 28.08, 28.08, 0, 0, 0],
                                   [0.0, 59.31, 28.07, 0, 0, 0],
                                   [28.08, 28.07, 59.32, 0, 0, 0],
                                   [0, 0, 0, 26.35, 0, 0],
                                   [0, 0, 0, 0, 26.35, 0],
                                   [0, 0, 0, 0, 0, 26.35]])
         self.assertEqual(len(w), 1)
Beispiel #2
0
 def test_from_voigt(self):
     with self.assertRaises(ValueError):
         ElasticTensor.from_voigt([[59.33, 28.08, 28.08, 0],
                                   [28.08, 59.31, 28.07, 0],
                                   [28.08, 28.07, 59.32, 0, 0],
                                   [0, 0, 0, 26.35, 0], [0, 0, 0, 0,
                                                         26.35]])
     with warnings.catch_warnings(record=True) as w:
         ElasticTensor.from_voigt([[59.33, 28.08, 28.08, 0, 0, 0],
                                   [0.0, 59.31, 28.07, 0, 0, 0],
                                   [28.08, 28.07, 59.32, 0, 0, 0],
                                   [0, 0, 0, 26.35, 0, 0],
                                   [0, 0, 0, 0, 26.35, 0],
                                   [0, 0, 0, 0, 0, 26.35]])
         self.assertEqual(len(w), 1)
def plug_in(symbol_values):
    tensor = ElasticTensor.from_voigt(symbol_values["C_ij"])
    structure = symbol_values["structure"]
    to_return = tensor.clarke_thermalcond(structure)
    if not isinstance(to_return, float):
        to_return = float(to_return)
    return {'t': to_return}
Beispiel #4
0
    def test_init(self):
        # Film VO2
        film = SpacegroupAnalyzer(self.get_structure("VO2"), symprec=0.1).get_conventional_standard_structure()

        # Substrate TiO2
        substrate = SpacegroupAnalyzer(self.get_structure("TiO2"), symprec=0.1).get_conventional_standard_structure()

        film_elac = ElasticTensor.from_voigt(
            [
                [324.32, 187.3, 170.92, 0.0, 0.0, 0.0],
                [187.3, 324.32, 170.92, 0.0, 0.0, 0.0],
                [170.92, 170.92, 408.41, 0.0, 0.0, 0.0],
                [0.0, 0.0, 0.0, 150.73, 0.0, 0.0],
                [0.0, 0.0, 0.0, 0.0, 150.73, 0.0],
                [0.0, 0.0, 0.0, 0.0, 0.0, 238.74],
            ]
        )

        s = SubstrateAnalyzer()

        matches = list(s.calculate(film, substrate, film_elac))
        self.assertEqual(len(matches), 192)
        for match in matches:
            assert match is not None
            assert isinstance(match.match_area, float)
Beispiel #5
0
    def test_energy_density(self):

        film_elac = ElasticTensor.from_voigt(
            [[324.32, 187.3, 170.92, 0., 0., 0.],
             [187.3, 324.32, 170.92, 0., 0., 0.],
             [170.92, 170.92, 408.41, 0., 0., 0.],
             [0., 0., 0., 150.73, 0., 0.], [0., 0., 0., 0., 150.73, 0.],
             [0., 0., 0., 0., 0., 238.74]])

        dfm = Deformation([[-9.86004855e-01, 2.27539582e-01, -4.64426035e-17],
                           [-2.47802121e-01, -9.91208483e-01, -7.58675185e-17],
                           [-6.12323400e-17, -6.12323400e-17, 1.00000000e+00]])

        self.assertAlmostEqual(
            film_elac.energy_density(dfm.green_lagrange_strain),
            0.00125664672793)

        film_elac.energy_density(
            Strain.from_deformation([[0.99774738, 0.11520994, -0.],
                                     [-0.11520994, 0.99774738, 0.],
                                     [
                                         -0.,
                                         -0.,
                                         1.,
                                     ]]))
Beispiel #6
0
    def setUp(self):
        self.voigt_1 = [[59.33, 28.08, 28.08, 0, 0, 0],
                        [28.08, 59.31, 28.07, 0, 0, 0],
                        [28.08, 28.07, 59.32, 0, 0, 0], [0, 0, 0, 26.35, 0, 0],
                        [0, 0, 0, 0, 26.35, 0], [0, 0, 0, 0, 0, 26.35]]
        mat = np.random.randn(6, 6)
        mat = mat + np.transpose(mat)
        self.rand_elastic_tensor = ElasticTensor.from_voigt(mat)
        self.ft = np.array([[[[59.33, 0, 0], [0, 28.08, 0], [0, 0, 28.08]],
                             [[0, 26.35, 0], [26.35, 0, 0], [0, 0, 0]],
                             [[0, 0, 26.35], [0, 0, 0], [26.35, 0, 0]]],
                            [[[0, 26.35, 0], [26.35, 0, 0], [0, 0, 0]],
                             [[28.08, 0, 0], [0, 59.31, 0], [0, 0, 28.07]],
                             [[0, 0, 0], [0, 0, 26.35], [0, 26.35, 0]]],
                            [[[0, 0, 26.35], [0, 0, 0], [26.35, 0, 0]],
                             [[0, 0, 0], [0, 0, 26.35], [0, 26.35, 0]],
                             [[28.08, 0, 0], [0, 28.07, 0], [0, 0, 59.32]]]])

        self.elastic_tensor_1 = ElasticTensor(self.ft)
        filepath = os.path.join(test_dir, 'Sn_def_stress.json')
        with open(filepath) as f:
            self.def_stress_dict = json.load(f)
        with open(os.path.join(test_dir, 'test_toec_data.json')) as f:
            self.toec_dict = json.load(f)
        self.structure = self.get_structure("Sn")

        warnings.simplefilter("always")
   def _evaluate(self, symbol_values):

       tensor = ElasticTensor.from_voigt(symbol_values["C_ij"])
       structure = symbol_values["_structure"]

       return {
           't': tensor.clarke_thermalcond(structure)
       }
    def setUp(self):
        # Empty aggregated collection
        self.test_elasticity_agg = MongoStore("test_emmet", "elasticity_agg")
        self.test_elasticity_agg.connect()

        # Generate test materials collection
        self.test_materials = MongoStore("test_emmet", "materials")
        self.test_materials.connect()
        mat_docs = []
        for n, formula in enumerate(['Si', 'BaNiO3', 'Li2O2', 'TiO2']):
            structure = PymatgenTest.get_structure(formula)
            structure.add_site_property("magmoms", [0.0] * len(structure))
            mat_docs.append({
                "task_id": "mp-{}".format(n),
                "structure": structure.as_dict(),
                "pretty_formula": formula
            })
        self.test_materials.update(mat_docs, update_lu=False)

        # Create elasticity collection and add docs
        self.test_elasticity = MongoStore("test_emmet",
                                          "elasticity",
                                          key="optimization_task_id")
        self.test_elasticity.connect()

        si = PymatgenTest.get_structure("Si")
        si.add_site_property("magmoms", [0.0] * len(si))
        et = ElasticTensor.from_voigt([[50, 25, 25, 0, 0, 0],
                                       [25, 50, 25, 0, 0, 0],
                                       [25, 25, 50, 0, 0, 0],
                                       [0, 0, 0, 75, 0,
                                        0], [0, 0, 0, 0, 75, 0],
                                       [0, 0, 0, 0, 0, 75]])
        doc = {
            "input_structure": si.copy().as_dict(),
            "order": 2,
            "magnetic_type": "non-magnetic",
            "optimization_task_id": "mp-1",
            "last_updated": datetime.utcnow(),
            "completed_at": datetime.utcnow(),
            "optimized_structure": si.copy().as_dict(),
            "pretty_formula": "Si",
            "state": "successful"
        }
        doc['elastic_tensor'] = et.voigt
        doc.update(et.property_dict)
        self.test_elasticity.update([doc])
        # Insert second doc with diff params
        si.perturb(0.005)
        doc.update({
            "optimized_structure": si.copy().as_dict(),
            "updated_at": datetime.utcnow(),
            "optimization_task_id": "mp-5"
        })
        self.test_elasticity.update([doc])
        self.builder = self.get_a_new_builder()
Beispiel #9
0
def get_et(elast_str=""):
    cij = np.empty((6, 6), dtype=float)
    elast = np.array(elast_str.split(","), dtype="float")
    count = 0
    for ii in range(6):
        for jj in range(6):
            cij[ii][jj] = elast[count]
            count = count + 1
    et = ElasticTensor.from_voigt(cij)
    return et
Beispiel #10
0
def get_et(elast_str=''):
    if elast_str == 'na':
        return 'na'
    else:
        cij = np.empty((6, 6), dtype=float)
        elast = np.array(elast_str.split(','), dtype='float')
        count = 0
        for ii in range(6):
            for jj in range(6):
                cij[ii][jj] = elast[count]
                count = count + 1
        et = ElasticTensor.from_voigt(cij)
        return et
Beispiel #11
0
    def process_item(self, item):
        """
        Process the tasks and materials into an elasticity collection

        Args:
            item: a dictionary of documents keyed by materials id

        Returns:
            an elasticity document
        """
        all_docs = []
        tasks, material_dict = item
        if not tasks:
            return all_docs
        grouped = group_by_task_id(material_dict, tasks)
        for mp_id, task_sets in grouped.items():
            elastic_docs = []
            for opt_task, defo_tasks in task_sets:
                elastic_doc = get_elastic_analysis(opt_task, defo_tasks)
                if elastic_doc:
                    elastic_docs.append(elastic_doc)

            if not elastic_docs:
                logger.warning("No elastic doc for mp_id {}".format(mp_id))
                continue

            # For now just do the most recent one that's not failed
            sorted(elastic_docs, key=lambda x: (x['state'], x['completed_at']))
            final_doc = elastic_docs[-1]
            c_ijkl = ElasticTensor.from_voigt(final_doc['elastic_tensor'])
            structure = final_doc['optimized_structure']
            formula = structure.composition.reduced_formula
            elements = [s.symbol for s in structure.composition.elements]
            chemsys = '-'.join(elements)
            final_doc.update(c_ijkl.property_dict)
            final_doc.update(c_ijkl.get_structure_property_dict(structure))

            elastic_summary = {
                'task_id': mp_id,
                'all_elastic_fits': elastic_docs,
                'elasticity': final_doc,
                'pretty_formula': formula,
                'chemsys': chemsys,
                'elements': elements,
                'last_updated': self.elasticity.lu_field
            }
            all_docs.append(elastic_summary)
            # elastic_summary.update(final_doc)

        return all_docs
Beispiel #12
0
    def test_energy_density(self):

        film_elac = ElasticTensor.from_voigt([
            [324.32,  187.3,   170.92,    0.,      0.,      0.],
            [187.3,   324.32,  170.92,    0.,      0.,      0.],
            [170.92,  170.92,  408.41,    0.,      0.,      0.],
            [0.,      0.,      0.,    150.73,    0.,      0.],
            [0.,      0.,      0.,      0.,    150.73,    0.],
            [0.,      0.,      0.,      0.,      0.,    238.74]])

        dfm = Deformation([[ -9.86004855e-01,2.27539582e-01,-4.64426035e-17],
                           [ -2.47802121e-01,-9.91208483e-01,-7.58675185e-17],
                           [ -6.12323400e-17,-6.12323400e-17,1.00000000e+00]])

        self.assertAlmostEqual(film_elac.energy_density(dfm.green_lagrange_strain),
            0.000125664672793)
    def setUp(self):
        self.voigt_1 = [[59.33, 28.08, 28.08, 0, 0, 0],
                        [28.08, 59.31, 28.07, 0, 0, 0],
                        [28.08, 28.07, 59.32, 0, 0, 0],
                        [0, 0, 0, 26.35, 0, 0],
                        [0, 0, 0, 0, 26.35, 0],
                        [0, 0, 0, 0, 0, 26.35]]
        mat = np.random.randn(6, 6)
        mat = mat + np.transpose(mat)
        self.rand_elastic_tensor = ElasticTensor.from_voigt(mat)
        self.ft = np.array([[[[59.33, 0, 0],
                              [0, 28.08, 0],
                              [0, 0, 28.08]],
                             [[0, 26.35, 0],
                              [26.35, 0, 0],
                              [0, 0, 0]],
                             [[0, 0, 26.35],
                              [0, 0, 0],
                              [26.35, 0, 0]]],
                            [[[0, 26.35, 0],
                              [26.35, 0, 0],
                              [0, 0, 0]],
                             [[28.08, 0, 0],
                              [0, 59.31, 0],
                              [0, 0, 28.07]],
                             [[0, 0, 0],
                              [0, 0, 26.35],
                              [0, 26.35, 0]]],
                            [[[0, 0, 26.35],
                              [0, 0, 0],
                              [26.35, 0, 0]],
                             [[0, 0, 0],
                              [0, 0, 26.35],
                              [0, 26.35, 0]],
                             [[28.08, 0, 0],
                              [0, 28.07, 0],
                              [0, 0, 59.32]]]])

        self.elastic_tensor_1 = ElasticTensor(self.ft)
        filepath = os.path.join(test_dir, 'Sn_def_stress.json')
        with open(filepath) as f:
            self.def_stress_dict = json.load(f)
        with open(os.path.join(test_dir, 'test_toec_data.json')) as f:
            self.toec_dict = json.load(f)
        self.structure = self.get_structure("Sn")

        warnings.simplefilter("always")
    def runTest(self):
        # Film VO2
        film = SpacegroupAnalyzer(self.get_structure("VO2"),
                                  symprec=0.1).get_conventional_standard_structure()

        # Substrate TiO2
        substrate = SpacegroupAnalyzer(self.get_structure("TiO2"),
                                       symprec=0.1).get_conventional_standard_structure()

        film_elac = ElasticTensor.from_voigt([
            [324.32, 187.3, 170.92, 0., 0., 0.],
            [187.3, 324.32, 170.92, 0., 0., 0.],
            [170.92, 170.92, 408.41, 0., 0., 0.],
            [0., 0., 0., 150.73, 0., 0.],
            [0., 0., 0., 0., 150.73, 0.],
            [0., 0., 0., 0., 0., 238.74]])

        s = SubstrateAnalyzer()

        matches = list(s.calculate(film,substrate,film_elac))
        self.assertEqual(len(matches), 82)
    def runTest(self):
        # Film VO2
        film = SpacegroupAnalyzer(
            self.get_structure("VO2"),
            symprec=0.1).get_conventional_standard_structure()

        # Substrate TiO2
        substrate = SpacegroupAnalyzer(
            self.get_structure("TiO2"),
            symprec=0.1).get_conventional_standard_structure()

        film_elac = ElasticTensor.from_voigt(
            [[324.32, 187.3, 170.92, 0., 0., 0.],
             [187.3, 324.32, 170.92, 0., 0., 0.],
             [170.92, 170.92, 408.41, 0., 0., 0.],
             [0., 0., 0., 150.73, 0., 0.], [0., 0., 0., 0., 150.73, 0.],
             [0., 0., 0., 0., 0., 238.74]])

        s = SubstrateAnalyzer()

        matches = list(s.calculate(film, substrate, film_elac))
        self.assertEqual(len(matches), 82)
Beispiel #16
0
def elastic_props(outcar="", vacuum=False):
    """
    Obtain elastic tensor and calculate related properties

    Args:
        outcar: OUTCAR file path
        vacuum: whether the structure has vaccum such as 2D materials
        for vacuum structures bulk and shear mod. needs extra attenstion
        and elastic tensor are in Nm^-1 rather than GPa
    Returns:
          info: data for elastic tensor (in string and object representation), bulk, shear modulus, and phonon modes
    """
    if vacuum == True:
        contcar = Structure.from_file(str(outcar).replace("OUTCAR", "POSCAR"))
        ratio_c = 0.1 * float(abs(
            contcar.lattice.matrix[2][2]))  # *(10**9)*(10**-10) #N/m unit
    el_tens = "na"
    KV = "na"
    GV = "na"
    spin = "na"
    info = {}
    ratio_c = 1.0
    v = open(outcar, "r")
    lines = v.read().splitlines()
    for i, line in enumerate(lines):
        if "TOTAL ELASTIC MODULI (kBar)" in line:
            c11 = lines[i + 3].split()[1]
            c12 = lines[i + 3].split()[2]
            c13 = lines[i + 3].split()[3]
            c14 = lines[i + 3].split()[4]
            c15 = lines[i + 3].split()[5]
            c16 = lines[i + 3].split()[6]
            c21 = lines[i + 4].split()[1]
            c22 = lines[i + 4].split()[2]
            c23 = lines[i + 4].split()[3]
            c24 = lines[i + 4].split()[4]
            c25 = lines[i + 4].split()[5]
            c26 = lines[i + 4].split()[6]
            c31 = lines[i + 5].split()[1]
            c32 = lines[i + 5].split()[2]
            c33 = lines[i + 5].split()[3]
            c34 = lines[i + 5].split()[4]
            c35 = lines[i + 5].split()[5]
            c36 = lines[i + 5].split()[6]
            c41 = lines[i + 6].split()[1]
            c42 = lines[i + 6].split()[2]
            c43 = lines[i + 6].split()[3]
            c44 = lines[i + 6].split()[4]
            c45 = lines[i + 6].split()[5]
            c46 = lines[i + 6].split()[6]
            c51 = lines[i + 7].split()[1]
            c52 = lines[i + 7].split()[2]
            c53 = lines[i + 7].split()[3]
            c54 = lines[i + 7].split()[4]
            c55 = lines[i + 7].split()[5]
            c56 = lines[i + 7].split()[6]
            c61 = lines[i + 8].split()[1]
            c62 = lines[i + 8].split()[2]
            c63 = lines[i + 8].split()[3]
            c64 = lines[i + 8].split()[4]
            c65 = lines[i + 8].split()[5]
            c66 = lines[i + 8].split()[6]
            c11 = round(ratio_c * float(c11) / float(10), 1)
            c12 = round(ratio_c * float(c12) / float(10), 1)
            c13 = round(ratio_c * float(c13) / float(10), 1)
            c14 = round(ratio_c * float(c14) / float(10), 1)
            c15 = round(ratio_c * float(c15) / float(10), 1)
            c16 = round(ratio_c * float(c16) / float(10), 1)
            c21 = round(ratio_c * float(c21) / float(10), 1)
            c22 = round(ratio_c * float(c22) / float(10), 1)
            c23 = round(ratio_c * float(c23) / float(10), 1)
            c24 = round(ratio_c * float(c24) / float(10), 1)
            c25 = round(ratio_c * float(c25) / float(10), 1)
            c26 = round(ratio_c * float(c26) / float(10), 1)
            c31 = round(float(c31) / float(10), 1)
            c32 = round(float(c32) / float(10), 1)
            c33 = round(float(c33) / float(10), 1)
            c34 = round(float(c34) / float(10), 1)
            c35 = round(float(c35) / float(10), 1)
            c36 = round(float(c36) / float(10), 1)
            c41 = round(float(c41) / float(10), 1)
            c42 = round(float(c42) / float(10), 1)
            c43 = round(float(c43) / float(10), 1)
            c44 = round(float(c44) / float(10), 1)
            c45 = round(float(c45) / float(10), 1)
            c46 = round(float(c46) / float(10), 1)
            c51 = round(float(c51) / float(10), 1)
            c52 = round(float(c52) / float(10), 1)
            c53 = round(float(c53) / float(10), 1)
            c54 = round(float(c54) / float(10), 1)
            c55 = round(float(c55) / float(10), 1)
            c56 = round(float(c56) / float(10), 1)
            c61 = round(float(c61) / float(10), 1)
            c62 = round(float(c62) / float(10), 1)
            c63 = round(float(c63) / float(10), 1)
            c64 = round(float(c64) / float(10), 1)
            c65 = round(float(c65) / float(10), 1)
            c66 = round(float(c66) / float(10), 1)
            KV = float((c11 + c22 + c33) + 2 * (c12 + c23 + c31)) / float(9)
            GV = float((c11 + c22 + c33) - (c12 + c23 + c31) + 3 *
                       (c44 + c55 + c66)) / float(15)
            KV = round(KV, 3)
            GV = round(GV, 3)
            break
    v.close()

    # Convenient string representation for storage

    el_tens = (str(c11) + str(",") + str(c12) + str(",") + str(c13) +
               str(",") + str(c14) + str(",") + str(c15) + str(",") +
               str(c16) + str(",") + str(c21) + str(",") + str(c22) +
               str(",") + str(c23) + str(",") + str(c24) + str(",") +
               str(c25) + str(",") + str(c26) + str(",") + str(c31) +
               str(",") + str(c32) + str(",") + str(c33) + str(",") +
               str(c34) + str(",") + str(c35) + str(",") + str(c36) +
               str(",") + str(c41) + str(",") + str(c42) + str(",") +
               str(c43) + str(",") + str(c44) + str(",") + str(c45) +
               str(",") + str(c46) + str(",") + str(c51) + str(",") +
               str(c52) + str(",") + str(c53) + str(",") + str(c54) +
               str(",") + str(c55) + str(",") + str(c56) + str(",") +
               str(c61) + str(",") + str(c62) + str(",") + str(c63) +
               str(",") + str(c64) + str(",") + str(c65) + str(",") + str(c66))

    cij = np.empty((6, 6), dtype=float)
    elast = np.array(el_tens.split(","), dtype="float")
    count = 0
    for ii in range(6):
        for jj in range(6):
            cij[ii][jj] = elast[count]
    el_tens2 = ElasticTensor.from_voigt(cij)

    modes = []
    try:
        for i in lines:
            if "cm-1" in i and "meV" in i:
                mod = float(i.split()[7])
                if mod not in modes:
                    modes.append(float(mod))
    except:
        pass

    info["el_tens_str"] = el_tens
    info["el_tens_obj"] = el_tens2
    info["KV"] = KV
    info["GV"] = GV
    info["modes"] = modes

    return info
Beispiel #17
0
    def process_item(self, item):
        """
        Calculates substrate matches for all given substrates

        Args:
            item (dict): a dict with a material_id and a structure

        Returns:
            dict: a diffraction dict
        """
        substrates = self.__settings

        elastic_tensor = item.get("elastic_tensor", None)
        elastic_tensor = ElasticTensor.from_voigt(
            elastic_tensor) if elastic_tensor else None

        self.logger.debug("Calculating substrates for {}".format(
            item["task_id"]))

        film = Structure.from_dict(item["structure"])

        all_matches = []

        sa = SubstrateAnalyzer()

        for s in substrates:

            substrate = s["structure"]

            # Calculate lowest matches and group by substrate orientation
            matches_by_orient = groupby_itemkey(
                sa.calculate(film, substrate, elastic_tensor, lowest=True),
                "sub_miller")

            # Find the lowest area match for each substrate orientation
            lowest_matches = [
                min(g, key=itemgetter("match_area"))
                for k, g in matches_by_orient
            ]

            for match in lowest_matches:
                db_entry = {
                    "sub_id": s["task_id"],
                    "orient": " ".join(map(str, match["sub_miller"])),
                    "sub_form": substrate.composition.reduced_formula,
                    "film_orient": " ".join(map(str, match["film_miller"])),
                    "area": match["match_area"],
                }

                if "elastic_energy" in match:
                    db_entry["energy"] = match["elastic_energy"]
                    db_entry["strain"] = match["strain"]

                all_matches.append(db_entry)

        # Sort based on energy if an elastic tensor is present otherwise the area
        if elastic_tensor is not None:
            sort_key = itemgetter("energy")
        else:
            sort_key = itemgetter("area")

        all_matches = list(sorted(all_matches, key=sort_key))

        d = {self.substrates.key: item["task_id"], "substrates": all_matches}

        return d
Beispiel #18
0
    def get_pmg_elastic_tensor(self):
        """
        Converts to a pymatgen ElasticTensor object.
        """

        return ElasticTensor.from_voigt(self.elastic_tensor)