Ejemplo n.º 1
0
 def update_composite_models(self, super_models):
     """
     Add / redefine user-defined super_models to the graph.
     If the input, super_models, includes keys in self._super_models, they are redefined.
     The addition of a super_model may fail if appropriate Symbol objects are not already on the graph.
     If any addition operation fails, the entire update is aborted.
     Args:
         super_models (dict<str, SuperModel>): Instances of the SuperModel class
     Returns:
         None
     """
     added = {}
     for model in super_models.values():
         self._composite_models[model.name] = model
         added[model.name] = model
         for input_set in model.input_sets:
             for input in input_set:
                 input = CompositeModel.get_symbol(input)
                 if input not in self._symbol_types.keys():
                     raise KeyError(
                         "Attempted to add a model to the property "
                         "network with an unrecognized Symbol. "
                         "Add {} Symbol to the property network before "
                         "adding this model.".format(input))
Ejemplo n.º 2
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