コード例 #1
0
ファイル: test_models.py プロジェクト: vtshitoyan/propnet
    def test_model_returns_complex(self):
        # This tests model failure with scalar complex.
        # Quantity class has other more thorough tests.

        A = Symbol('a', ['A'], ['A'], units='dimensionless', shape=1)
        B = Symbol('b', ['B'], ['B'], units='dimensionless', shape=1)
        get_config = {
            'name': 'add_complex_value',
            # 'connections': [{'inputs': ['b'], 'outputs': ['a']}],
            'equations': ['a = b + 1j'],
            # 'unit_map': {'a': "dimensionless", 'a': "dimensionless"}
            'symbol_property_map': {
                "a": A,
                "b": B
            }
        }
        model = EquationModel(**get_config)
        out = model.evaluate({'b': Quantity(B, 5)}, allow_failure=True)
        self.assertFalse(out['successful'])
        self.assertEqual(out['message'],
                         'Evaluation returned invalid values (complex)')

        out = model.evaluate({'b': Quantity(B, 5j)}, allow_failure=True)
        self.assertTrue(out['successful'])
        self.assertTrue(np.isclose(out['a'].magnitude, 6j))
コード例 #2
0
ファイル: test_models.py プロジェクト: yoshida-lab/propnet
    def test_unit_handling(self):
        """
        Tests unit handling with a simple model that calculates the area of a rectangle as the
        product of two lengths.

        In this case the input lengths are provided in centimeters and meters.
        Tests whether the input units are properly coerced into canonical types.
        Tests whether the output units are properly set.
        Tests whether the model returns as predicted.
        Returns:
            None
        """
        L = Symbol('l', ['L'], ['L'], units=[1.0, [['centimeter', 1.0]]], shape=[1])
        A = Symbol('a', ['A'], ['A'], units=[1.0, [['centimeter', 2.0]]], shape=[1])
        get_area_config = {
            'name': 'area',
            # 'connections': [{'inputs': ['l1', 'l2'], 'outputs': ['a']}],
            'equations': ['a = l1 * l2'],
            # 'unit_map': {'l1': "cm", "l2": "cm", 'a': "cm^2"}
            'symbol_property_map': {"a": A, "l1": L, "l2": L}
        }
        model = EquationModel(**get_area_config)
        out = model.evaluate({'l1': Quantity(L, 1, 'meter'),
                              'l2': Quantity(L, 2)}, allow_failure=False)

        self.assertTrue(math.isclose(out['a'].magnitude, 200.0))
        self.assertTrue(out['a'].units == A.units)
コード例 #3
0
ファイル: models.py プロジェクト: jmmshn/propnet
    def test(self, inputs, outputs):
        """
        Runs a test of the model to determine whether its operation
        is consistent with the specified inputs and outputs

        Args:
            inputs (dict): set of input names to values
            outputs (dict): set of output names to values

        Returns (bool): True if test succeeds
        """
        evaluate_inputs = self.map_symbols_to_properties(inputs)
        evaluate_inputs = {s: Quantity(s, v, self.unit_map.get(s))
                           for s, v in evaluate_inputs.items()}
        evaluate_outputs = self.evaluate(evaluate_inputs, allow_failure=False)
        evaluate_outputs = self.map_properties_to_symbols(evaluate_outputs)
        errmsg = "{} model test failed on ".format(self.name) + "{}\n"
        errmsg += "{}(test data) = {}\n"#.format(k, known_output)
        errmsg += "{}(model output) = {}"#.format(k, plug_in_output)
        for k, known_output in outputs.items():
            symbol = self.symbol_property_map[k]
            units = self.unit_map.get(k)
            known_quantity = Quantity(symbol, known_output, units)
            evaluate_output = evaluate_outputs[k]
            if known_quantity.is_pint or isinstance(known_quantity.value, list):
                if not np.allclose(known_quantity.value, evaluate_output.value):
                    errmsg = errmsg.format("evaluate", k, evaluate_output,
                                           k, known_quantity)
                    raise ModelEvaluationError(errmsg)
            elif known_quantity != evaluate_output:
                errmsg = errmsg.format("evaluate", k, evaluate_output,
                                       k, known_quantity)
                raise ModelEvaluationError(errmsg)

        return True
コード例 #4
0
ファイル: test_material.py プロジェクト: yoshida-lab/propnet
 def test_add_default_quantities(self):
     material = Material(add_default_quantities=True)
     self.assertEqual(
         list(material['temperature'])[0], Quantity("temperature", 300))
     self.assertEqual(
         list(material['relative_permeability'])[0],
         Quantity("relative_permeability", 1))
コード例 #5
0
ファイル: test_quantity.py プロジェクト: yoshida-lab/propnet
 def test_from_weighted_mean(self):
     qlist = [
         Quantity(self.custom_symbol, val)
         for val in np.arange(1, 2.01, 0.01)
     ]
     qagg = Quantity.from_weighted_mean(qlist)
     self.assertAlmostEqual(qagg.magnitude, 1.5)
     self.assertAlmostEqual(qagg.uncertainty, 0.2915475947422652)
コード例 #6
0
    def process_item(self, item):
        # Define quantities corresponding to materials doc fields
        # Attach quantities to materials
        item = MontyDecoder().process_decoded(item)
        logger.info("Populating material for %s", item['task_id'])
        material = Material()
        for mkey, property_name in self.materials_symbol_map.items():
            value = get(item, mkey)
            if value:
                material.add_quantity(Quantity(property_name, value))

        # Add custom things, e. g. computed entry
        computed_entry = get_entry(item)
        material.add_quantity(Quantity("computed_entry", computed_entry))
        material.add_quantity(
            Quantity("external_identifier_mp", item['task_id']))

        input_quantities = material.get_quantities()

        # Use graph to generate expanded quantity pool
        logger.info("Evaluating graph for %s", item['task_id'])
        graph = Graph()
        graph.remove_models({
            "dimensionality_cheon":
            DEFAULT_MODEL_DICT['dimensionality_cheon'],
            "dimensionality_gorai":
            DEFAULT_MODEL_DICT['dimensionality_gorai']
        })
        new_material = graph.evaluate(material)

        # Format document and return
        logger.info("Creating doc for %s", item['task_id'])
        doc = {"inputs": [quantity.as_dict() for quantity in input_quantities]}
        for symbol, quantity in new_material.get_aggregated_quantities().items(
        ):
            all_qs = new_material._symbol_to_quantity[symbol]
            # Only add new quantities
            if len(all_qs) == 1 and list(all_qs)[0] in input_quantities:
                continue
            qs = [quantity.as_dict() for quantity in all_qs]
            sub_doc = {
                "quantities": qs,
                "mean": unumpy.nominal_values(quantity.value).tolist(),
                "std_dev": unumpy.std_devs(quantity.value).tolist(),
                "units": qs[0]['units'],
                "title": quantity._symbol_type.display_names[0]
            }
            doc[symbol.name] = sub_doc
        doc.update({
            "task_id": item["task_id"],
            "pretty_formula": item["pretty_formula"]
        })
        return jsanitize(doc, strict=True)
コード例 #7
0
ファイル: test_quantity.py プロジェクト: yoshida-lab/propnet
    def test_properties(self):
        # Test units, magnitude
        q = Quantity("bulk_modulus", 100)
        self.assertEqual(q.units, "gigapascal")
        self.assertEqual(q.magnitude, 100)

        # Ensure non-pint values raise error with units, magnitude
        structure = PymatgenTest.get_structure('Si')
        q = Quantity("structure", structure)
        with self.assertRaises(ValueError):
            print(q.units)
        with self.assertRaises(ValueError):
            print(q.magnitude)
コード例 #8
0
 def setUp(self):
     # Create some test properties and a few base objects
     self.q1 = Quantity(
         DEFAULT_SYMBOLS['bulk_modulus'],
         ureg.Quantity.from_tuple([200, [['gigapascals', 1]]]))
     self.q2 = Quantity(
         DEFAULT_SYMBOLS['shear_modulus'],
         ureg.Quantity.from_tuple([100, [['gigapascals', 1]]]))
     self.q3 = Quantity(
         DEFAULT_SYMBOLS['bulk_modulus'],
         ureg.Quantity.from_tuple([300, [['gigapascals', 1]]]))
     self.material = Material()
     self.graph = Graph()
コード例 #9
0
 def generate_canonical_material(c_symbols):
     """
     Generates a Material with appropriately attached Quantities.
     Args:
         c_symbols: (dict<str, Symbol>) dictionary of defined materials.
     Returns:
         (Material) material with properties loaded.
     """
     q1 = Quantity(c_symbols['A'], 19)
     q2 = Quantity(c_symbols['A'], 23)
     m = Material()
     m.add_quantity(q1)
     m.add_quantity(q2)
     return m
コード例 #10
0
ファイル: test_quantity.py プロジェクト: yoshida-lab/propnet
 def test_quantity_construction(self):
     # From custom symbol
     q = Quantity(self.custom_symbol, 5.0)
     self.assertEqual(q.value.magnitude, 5.0)
     self.assertIsInstance(q.value, ureg.Quantity)
     # From canonical symbol
     q = Quantity("bulk_modulus", 100)
     self.assertEqual(q.value.magnitude, 100)
     # From custom symbol with constraint
     with self.assertRaises(SymbolConstraintError):
         Quantity(self.constraint_symbol, -500)
     # From canonical symbol with constraint
     with self.assertRaises(SymbolConstraintError):
         Quantity("bulk_modulus", -500)
コード例 #11
0
    def evaluate(input_rows):

        quantities = [
            Quantity(symbol_type=ROW_IDX_TO_SYMBOL_NAME[idx],
                     value=ureg.parse_expression(row['Value']))
            for idx, row in enumerate(input_rows) if row['Value']
        ]
        material = Material()

        for quantity in quantities:
            material.add_quantity(quantity)

        graph = Graph()
        output_material = graph.evaluate(material)

        output_quantities = output_material.get_aggregated_quantities()
        print(output_quantities)

        output_rows = [{
            'Property': symbol.display_names[0],
            'Value': str(quantity.value),
            'Provenance': None
        } for symbol, quantity in output_quantities.items()]

        return output_rows
コード例 #12
0
ファイル: recdict.py プロジェクト: darnoceloc/MPContribs
 def iterate(self, nested_dict=None):
     """http://stackoverflow.com/questions/10756427/loop-through-all-nested-dictionary-values"""
     d = self if nested_dict is None else nested_dict
     if nested_dict is None:
         self.level = 0
     for key in list(d.keys()):
         value = d[key]
         if isinstance(value, _Mapping):
             if value.get('@class') == 'Structure':
                 from pymatgen import Structure
                 yield key, Structure.from_dict(value)
                 continue
             yield (self.level, key), None
             if value.get('@class') == 'Table':
                 from mpcontribs.io.core.components.tdata import Table
                 yield key, Table.from_dict(value)
                 continue
             if Quantity is not None and value.get('@class') == 'Quantity':
                 quantity = Quantity.from_dict(value)
                 yield key, quantity
                 continue
             self.level += 1
             for inner_key, inner_value in self.iterate(nested_dict=value):
                 yield inner_key, inner_value
             self.level -= 1
         else:
             yield (self.level, key), value
コード例 #13
0
    def get_materials_for_mpids(self, mpids, filter_null_properties=True):
        """
        Retrieve a list of Materials from the materials
        Project for a given list of Materials Project IDs.

        Args:
            mpids: a list of Materials Project IDs

        Returns:

        """

        materials_properties = self.get_properties_for_mpids(
            mpids, filter_null_properties=filter_null_properties)
        materials = []

        for material_properties in materials_properties:
            material = Material()
            for property_name, property_value in material_properties.items():
                provenance = ProvenanceElement(source='Materials Project')
                quantity = Quantity(self.mapping[property_name],
                                    property_value,
                                    provenance=provenance)
                material.add_quantity(quantity)
            materials.append(material)

        return materials
コード例 #14
0
ファイル: test_quantity.py プロジェクト: yoshida-lab/propnet
 def test_get_provenance_graph(self):
     g = Graph()
     qs = [
         Quantity("bulk_modulus", 100),
         Quantity("shear_modulus", 50),
         Quantity("density", 8.96)
     ]
     mat = Material(qs)
     evaluated = g.evaluate(mat)
     # TODO: this should be tested more thoroughly
     out = list(evaluated['vickers_hardness'])[0]
     with tempfile.ScratchDir('.'):
         out.draw_provenance_graph("out.png")
     pgraph = out.get_provenance_graph()
     end = list(evaluated['vickers_hardness'])[0]
     shortest_lengths = nx.shortest_path_length(pgraph, qs[0])
     self.assertEqual(shortest_lengths[end], 4)
コード例 #15
0
    def evaluate(input_rows, data, aggregate):


        quantities = [Quantity(symbol_type=ROW_IDX_TO_SYMBOL_NAME[idx],
                               value=ureg.parse_expression(row['Editable Value']))
                      for idx, row in enumerate(input_rows) if row['Editable Value']]

        if data and len(data) > 0:
            quantities += json.loads(data, cls=MontyDecoder).values()

        if not quantities:
            raise PreventUpdate

        material = Material()

        for quantity in quantities:
            material.add_quantity(quantity)

        graph = Graph()
        output_material = graph.evaluate(material)

        if aggregate:
            output_quantities = output_material.get_aggregated_quantities().values()
        else:
            output_quantities = output_material.get_quantities()

        output_rows = [{
            'Property': quantity.symbol.display_names[0],
            'Value': quantity.pretty_string(3)
        } for quantity in output_quantities]

        output_table = dt.DataTable(id='output-table',
                                    rows=output_rows,
                                    editable=False)

        # TODO: clean up

        input_quantity_names = [q.symbol.name for q in quantities]
        derived_quantity_names = set(
            [q.symbol.name for q in output_quantities]) - \
                                 set(input_quantity_names)
        material_graph_data = graph_conversion(
            graph.get_networkx_graph(), nodes_to_highlight_green=input_quantity_names,
            nodes_to_highlight_yellow=list(derived_quantity_names))
        options = AESTHETICS['global_options']
        options['edges']['color'] = '#000000'
        output_graph = html.Div(GraphComponent(
            id='material-graph',
            graph=material_graph_data,
            options=options
        ), style={'width': '100%', 'height': '400px'})

        return [
            output_graph,
            html.Br(),
            output_table
        ]
コード例 #16
0
ファイル: test_quantity.py プロジェクト: vtshitoyan/propnet
    def test_numpy_scalar_conversion(self):
        # From custom symbol
        q_int = Quantity(self.custom_symbol, np.int64(5))
        q_float = Quantity(self.custom_symbol, np.float64(5.0))
        q_complex = Quantity(self.custom_symbol, np.complex64(5.0 + 1.j))

        self.assertTrue(isinstance(q_int.magnitude, int))
        self.assertTrue(isinstance(q_float.magnitude, float))
        self.assertTrue(isinstance(q_complex.magnitude, complex))

        q_int_uncertainty = Quantity(self.custom_symbol,
                                     5,
                                     uncertainty=np.int64(1))
        q_float_uncertainty = Quantity(self.custom_symbol,
                                       5.0,
                                       uncertainty=np.float64(1.0))
        q_complex_uncertainty = Quantity(self.custom_symbol,
                                         5.0 + 1j,
                                         uncertainty=np.complex64(1.0 + 0.1j))

        self.assertTrue(
            isinstance(q_int_uncertainty.uncertainty.magnitude, int))
        self.assertTrue(
            isinstance(q_float_uncertainty.uncertainty.magnitude, float))
        self.assertTrue(
            isinstance(q_complex_uncertainty.uncertainty.magnitude, complex))
コード例 #17
0
    def add_default_quantities(self):
        """
        Adds any default symbols which are not present in the graph

        Returns:
            None
        """
        new_syms = set(DEFAULT_SYMBOL_VALUES.keys())
        new_syms -= set(self._symbol_to_quantity.keys())
        for sym in new_syms:
            quantity = Quantity.from_default(sym)
            warnings.warn("Adding default {} quantity with value {}".format(
                sym, quantity))
            self.add_quantity(quantity)
コード例 #18
0
    def get_aggregated_quantities(self):
        """
        Return mean values for all quantities for each symbol.

        Returns:
            (dict<Symbol, weighted_mean) mapping from a Symbol to
            an aggregated statistic.
        """
        # TODO: proper weighting system, and more flexibility in object handling
        aggregated = {}
        for symbol, quantities in self._symbol_to_quantity.items():
            if not symbol.category == 'object':
                aggregated[symbol] = Quantity.from_weighted_mean(
                    list(quantities))
        return aggregated
コード例 #19
0
ファイル: fitting.py プロジェクト: yoshida-lab/propnet
def aggregate_quantities(quantities, model_score_dict=None):
    """
    Simple method for aggregating a set of quantities

    Args:
        quantities:
        model_score_dict:

    Returns:

    """
    symbol = next(iter(quantities)).symbol
    if not all([q.symbol == symbol for q in quantities]):
        raise ValueError("Quantities passed to aggregate must be same symbol")
    weights = [get_weight(q, model_score_dict) for q in quantities]
    result_value = sum(
        [w * q.value for w, q in zip(weights, quantities)]) / sum(weights)
    return Quantity(symbol, result_value)
コード例 #20
0
ファイル: test_models.py プロジェクト: yoshida-lab/propnet
    def test_model_returns_nan(self):
        # This tests model failure with scalar nan.
        # Quantity class has other more thorough tests.

        A = Symbol('a', ['A'], ['A'], units='dimensionless', shape=1)
        B = Symbol('b', ['B'], ['B'], units='dimensionless', shape=1)
        get_config = {
            'name': 'equality',
            # 'connections': [{'inputs': ['b'], 'outputs': ['a']}],
            'equations': ['a = b'],
            # 'unit_map': {'a': "dimensionless", 'a': "dimensionless"}
            'symbol_property_map': {"a": A, "b": B}
        }
        model = EquationModel(**get_config)
        out = model.evaluate({'b': Quantity(B, float('nan'))},
                             allow_failure=True)
        self.assertFalse(out['successful'])
        self.assertEqual(out['message'], 'Evaluation returned invalid values (NaN)')
コード例 #21
0
    def test_super_evaluate(self):
        """
        Tests the graph's composite material evaluation.
        """
        mpr = MPRester()
        m1 = mpr.get_material_for_mpid("mp-13")
        # Temporary hack for problem with zero band-gap materials
        m1.remove_symbol("band_gap_pbe")
        m1.add_quantity(Quantity("band_gap", 0.0))
        m2 = mpr.get_material_for_mpid("mp-24972")
        sm = CompositeMaterial([m1, m2])

        g = Graph()

        sm = g.super_evaluate(sm, allow_model_failure=False)

        self.assertTrue('pilling_bedworth_ratio' in sm._symbol_to_quantity.keys(),
                        "Super Evaluate failed to derive expected outputs.")
        self.assertTrue(len(sm._symbol_to_quantity['pilling_bedworth_ratio']) > 0,
                        "Super Evaluate failed to derive expected outputs.")
コード例 #22
0
    def test_provenance(self):
        model4 = EquationModel(name="model4", equations=["D=B*C*11"], constraints=["G==0"])
        symbols = GraphTest.generate_canonical_symbols()
        models = GraphTest.generate_canonical_models()
        models['model4'] = model4
        del models['model6']
        material = GraphTest.generate_canonical_material(symbols)
        g = Graph(symbol_types=symbols, models=models, composite_models=dict())
        material_derived = g.evaluate(material)

        expected_quantities = [
            Quantity(symbols['A'], 19),
            Quantity(symbols['A'], 23),
            Quantity(symbols['B'], 38),
            Quantity(symbols['B'], 46),
            Quantity(symbols['C'], 57),
            Quantity(symbols['C'], 69),
            Quantity(symbols['G'], 95),
            Quantity(symbols['G'], 115),
            Quantity(symbols['F'], 266),
            Quantity(symbols['F'], 322),
            Quantity(symbols['D'], 70395),
            Quantity(symbols['D'], 85215),
            Quantity(symbols['D'], 103155)
        ]

        for q in material_derived._symbol_to_quantity[symbols['A']]:
            self.assertTrue(q._provenance is None)
        for q in material_derived._symbol_to_quantity[symbols['B']]:
            if q.value == 38:
                self.assertTrue(q._provenance.model is models['model1'].name,
                                "provenance improperly calculated")
                self.assertTrue(expected_quantities[0] in q._provenance.inputs,
                                "provenance improperly calculated")
            else:
                self.assertTrue(q._provenance.model is models['model1'].name,
                                "provenance improperly calculated")
                self.assertTrue(expected_quantities[1] in q._provenance.inputs,
                                "provenance improperly calculated")
        for q in material_derived._symbol_to_quantity[symbols['C']]:
            if q.value == 57:
                self.assertTrue(q._provenance.model is models['model1'].name,
                                "provenance improperly calculated")
                self.assertTrue(expected_quantities[0] in q._provenance.inputs,
                                "provenance improperly calculated")
            else:
                self.assertTrue(q._provenance.model is models['model1'].name,
                                "provenance improperly calculated")
                self.assertTrue(expected_quantities[1] in q._provenance.inputs,
                                "provenance improperly calculated")
        for q in material_derived._symbol_to_quantity[symbols['G']]:
            if q.value == 95:
                self.assertTrue(q._provenance.model is models['model2'].name,
                                "provenance improperly calculated")
                self.assertTrue(expected_quantities[0] in q._provenance.inputs,
                                "provenance improperly calculated")
            else:
                self.assertTrue(q._provenance.model is models['model2'].name,
                                "provenance improperly calculated")
                self.assertTrue(expected_quantities[1] in q._provenance.inputs,
                                "provenance improperly calculated")
        for q in material_derived._symbol_to_quantity[symbols['D']]:
            if q.value == 70395:
                self.assertTrue(q._provenance.model is models['model5'].name,
                                "provenance improperly calculated")
                self.assertTrue(expected_quantities[4] in q._provenance.inputs,
                                "provenance improperly calculated")
                self.assertTrue(expected_quantities[6] in q._provenance.inputs,
                                "provenance improperly calculated")
コード例 #23
0
    def test_evaluate_single_material_degenerate_property(self):
        """
        Graph has one material on it: mat1
            mat1 has trivial degenerate properties relative permittivity and relative permeability
                2 experimental relative permittivity measurements
                2 experimental relative permeability measurements
        Determines if TestGraph1 is correctly evaluated using the evaluate method.
        We expect 4 refractive_index properties to be calculated as the following:
            sqrt(3), sqrt(5), sqrt(6), sqrt(10)
        """
        # Setup
        propnet = Graph()
        mat1 = Material()
        mat1.add_quantity(Quantity(DEFAULT_SYMBOLS['relative_permeability'], 1))
        mat1.add_quantity(Quantity(DEFAULT_SYMBOLS['relative_permeability'], 2))
        mat1.add_quantity(Quantity(DEFAULT_SYMBOLS['relative_permittivity'], 3))
        mat1.add_quantity(Quantity(DEFAULT_SYMBOLS['relative_permittivity'], 5))

        mat1_derived = propnet.evaluate(mat1)

        # Expected outputs
        s_outputs = []
        s_outputs.append(Quantity('relative_permeability', 1))
        s_outputs.append(Quantity('relative_permeability', 2))
        s_outputs.append(Quantity('relative_permittivity', 3))
        s_outputs.append(Quantity('relative_permittivity', 5))
        s_outputs.append(Quantity('refractive_index', 3 ** 0.5))
        s_outputs.append(Quantity('refractive_index', 5 ** 0.5))
        s_outputs.append(Quantity('refractive_index', 6 ** 0.5))
        s_outputs.append(Quantity('refractive_index', 10 ** 0.5))

        st_outputs = []
        st_outputs.append(DEFAULT_SYMBOLS['relative_permeability'])
        st_outputs.append(DEFAULT_SYMBOLS['relative_permittivity'])
        st_outputs.append(DEFAULT_SYMBOLS['refractive_index'])

        # Test
        for q_expected in s_outputs:
            q = None
            for q_derived in mat1_derived._symbol_to_quantity[q_expected.symbol]:
                if q_derived == q_expected:
                    q = q_derived
            self.assertTrue(q is not None,
                            "Quantity missing from evaluate.")
コード例 #24
0
    def test_evaluate_constraints_cyclic(self):
        """
        Tests the evaluation algorithm on a cyclic graph involving constraints.
        The canonical graph and the canonical material are used for this test.
        """
        model4 = EquationModel(name="model4", equations=["D=B*C*11"], constraints=["G==0"])

        symbols = GraphTest.generate_canonical_symbols()
        models = GraphTest.generate_canonical_models()
        models['model4'] = model4
        material = GraphTest.generate_canonical_material(symbols)
        g = Graph(symbol_types=symbols, models=models, composite_models=dict())
        material_derived = g.evaluate(material)

        expected_quantities = [
            Quantity(symbols['A'], 19),
            Quantity(symbols['A'], 23),
            Quantity(symbols['B'], 38),
            Quantity(symbols['B'], 46),
            Quantity(symbols['C'], 57),
            Quantity(symbols['C'], 69),
            Quantity(symbols['G'], 95),
            Quantity(symbols['G'], 115),
            Quantity(symbols['F'], 266),
            Quantity(symbols['F'], 322),
            Quantity(symbols['D'], 70395),
            Quantity(symbols['D'], 85215),
            Quantity(symbols['D'], 103155),
        ]

        self.assertTrue(material == GraphTest.generate_canonical_material(symbols),
                        "evaluate() mutated the original material argument.")

        derived_quantities = material_derived.get_quantities()
        self.assertTrue(len(expected_quantities) == len(derived_quantities),
                        "Evaluate did not correctly derive outputs.")
        for q in expected_quantities:
            self.assertTrue(q in material_derived._symbol_to_quantity[q.symbol],
                            "Evaluate failed to derive all outputs.")
            self.assertTrue(q in derived_quantities)
コード例 #25
0
ファイル: test_quantity.py プロジェクト: yoshida-lab/propnet
 def test_from_default(self):
     default = Quantity.from_default('temperature')
     self.assertEqual(default, Quantity('temperature', 300))
     default = Quantity.from_default('relative_permeability')
     self.assertEqual(default, Quantity("relative_permeability", 1))
コード例 #26
0
    def test_evaluate_cyclic(self):
        """
        Tests the evaluation algorithm on a cyclic graph.
        The canonical graph and the canonical material are used for this test.
        """
        symbols = GraphTest.generate_canonical_symbols()
        models = GraphTest.generate_canonical_models()
        material = GraphTest.generate_canonical_material(symbols)
        g = Graph(symbol_types=symbols, models=models, composite_models=dict())
        material_derived = g.evaluate(material)

        expected_quantities = [
            # Starting
            Quantity(symbols['A'], 19),
            Quantity(symbols['A'], 23),

            # Derives -1 (M1)
            Quantity(symbols['B'], 38),
            Quantity(symbols['B'], 46),
            Quantity(symbols['C'], 57),
            Quantity(symbols['C'], 69),
            # Derives -2 (M3, M1)
            Quantity(symbols['F'], 266),
            Quantity(symbols['F'], 322),
            # Derives -2 (M4, M1)
            Quantity(symbols['D'], 23826),
            Quantity(symbols['D'], 28842),
            Quantity(symbols['D'], 34914),

            # Derives -1 (M2)
            Quantity(symbols['G'], 95),
            Quantity(symbols['G'], 115),
            # Derives -2 (M5, M1, M2)
            Quantity(symbols['D'], 70395),
            Quantity(symbols['D'], 85215),
            Quantity(symbols['D'], 103155),
        ]

        self.assertTrue(material == GraphTest.generate_canonical_material(symbols),
                        "evaluate() mutated the original material argument.")

        derived_quantities = material_derived.get_quantities()
        self.assertTrue(len(expected_quantities) == len(derived_quantities),
                        "Evaluate did not correctly derive outputs.")
        for q in expected_quantities:
            self.assertTrue(q in material_derived._symbol_to_quantity[q.symbol],
                            "Evaluate failed to derive all outputs.")
            self.assertTrue(q in derived_quantities)
コード例 #27
0
    def super_evaluate(self, material, allow_model_failure=True):
        """
        Given a SuperMaterial object as input, creates a new SuperMaterial
        object to include all derivable properties.  Returns a reference to
        the new, augmented SuperMaterial object.

        Args:
            material (SuperMaterial): material for which properties
                will be expanded.

        Returns:
            (Material) reference to the newly derived material object.
        """

        if not isinstance(material, CompositeMaterial):
            raise Exception("material provided is not a SuperMaterial: " +
                            str(type(material)))

        # Evaluate material's sub-materials
        evaluated_materials = list()
        for m in material.materials:
            logger.debug("Evaluating sub-material: " + str(id(m)))
            if isinstance(m, CompositeMaterial):
                evaluated_materials.append(self.super_evaluate(m))
            else:
                evaluated_materials.append(self.evaluate(m))

        # Run all SuperModels in the graph on this SuperMaterial if
        # a material mapping can be established.  Store any derived quantities.
        all_quantities = defaultdict(set)
        for (k, v) in material._symbol_to_quantity:
            all_quantities[k].add(v)

        to_return = CompositeMaterial(evaluated_materials)
        to_return._symbol_to_quantity = all_quantities

        logger.debug("Evaluating SuperMaterial")

        for model in self._composite_models.values():

            logger.debug("\tEvaluating Model: " + model.name)

            # Establish material mappings for the given input set.

            mat_mappings = model.gen_material_mappings(to_return.materials)

            # Avoid ambiguous or impossible mappings, at least for now.
            if len(mat_mappings) != 1:
                continue

            mat_mapping = mat_mappings[0]

            # Go through input sets

            for property_input_sets in model.evaluation_list:

                logger.debug("\t\tGenerating input sets for: " +
                             str(property_input_sets))

                # Create a quantity pool from the appropriate materials.
                # Modify inputs for use in generate_input_sets

                temp_pool = defaultdict(set)
                combined_list = []
                mat_list = []
                symbol_list = []
                for item in property_input_sets:
                    combined_list.append(item)
                    mat_list.append(CompositeModel.get_material(item))
                    symbol_list.append(CompositeModel.get_symbol(item))
                for i in range(0, len(mat_list)):
                    if mat_list[
                            i] == None:  # Draw symbol from the CompositeMaterial
                        mat = to_return
                    else:
                        mat = mat_mapping[mat_list[i]]
                    for q in mat._symbol_to_quantity[symbol_list[i]]:
                        temp_pool[combined_list[i]].add(q)
                input_sets = self.generate_input_sets(combined_list, temp_pool)

                for input_set in input_sets:

                    logger.debug("\t\t\tEvaluating input set: " +
                                 str(input_set))

                    # Check if input_set can be evaluated -- input_set must pass the necessary model constraints
                    if not model.check_constraints(input_set):
                        logger.debug(
                            "\t\t\tInput set failed -- did not pass model constraints."
                        )
                        continue

                    # Try to evaluate input_set:
                    evaluate_set = dict(zip(combined_list, input_set))
                    output = model.evaluate(evaluate_set,
                                            allow_failure=allow_model_failure)
                    success = output.pop('successful')
                    if not success:
                        logger.debug(
                            "\t\t\tInput set failed -- did not produce a successful output."
                        )
                        continue

                    # input_set led to output from the Model -- add output to the SuperMaterial

                    logger.debug("\t\t\tInput set produced successful output.")
                    for symbol, quantity in output.items():
                        st = self._symbol_types.get(symbol)
                        if not st:
                            raise ValueError(
                                "Symbol type {} not found".format(symbol))
                        q = Quantity(st, quantity)
                        to_return._symbol_to_quantity[st].add(q)
                        logger.debug("\t\t\tNew output: " + str(q))

        # Evaluate the SuperMaterial's quantities and return the result.
        mappings = self.evaluate(to_return)._symbol_to_quantity
        to_return._symbol_to_quantity = mappings
        return to_return
コード例 #28
0
ファイル: test_quantity.py プロジェクト: yoshida-lab/propnet
 def test_to(self):
     quantity = Quantity('band_gap', 3.0, 'eV')
     new = quantity.to('joules')
     self.assertEqual(new.magnitude, 4.80652959e-19)
     self.assertEqual(new.units, 'joule')
コード例 #29
0
ファイル: test_quantity.py プロジェクト: yoshida-lab/propnet
 def test_pretty_string(self):
     quantity = Quantity('bulk_modulus', 100)
     self.assertEqual(quantity.pretty_string(3), "100 GPa")
コード例 #30
0
 def test_derive_quantities(self):
     # Simple one quantity test
     quantity = Quantity("band_gap", 3.2)
     graph = Graph()
     new, qpool = graph.derive_quantities([quantity])
     new_mat = graph.evaluate(Material([quantity]))