def _build_model(self, input_ivc: om.IndepVarComp = None) -> om.Group: """ Builds the model as defined in the configuration file. The model is initialized as a new group and populated with subsystems indicated in configuration file. :return: the built model """ model = FASTOADModel() model.active_submodels = self._serializer.data.get(KEY_SUBMODELS, {}) if input_ivc: model.add_subsystem("fastoad_inputs", input_ivc, promotes=["*"]) model_definition = self._serializer.data.get(KEY_MODEL) try: if KEY_COMPONENT_ID in model_definition: # The defined model is only one system system_id = model_definition[KEY_COMPONENT_ID] sub_component = RegisterOpenMDAOSystem.get_system(system_id) model.add_subsystem("system", sub_component, promotes=["*"]) else: # The defined model is a group self._parse_problem_table(model, model_definition) except FASTConfigurationBaseKeyBuildingError as err: log_err = err.__class__(err, KEY_MODEL) _LOGGER.error(log_err) raise log_err return model
def _build_model(self, problem: FASTOADProblem): """ Builds the problem model as defined in the configuration file. The problem model is populated with subsystems indicated in configuration file. """ model = problem.model model.active_submodels = self._serializer.data.get(KEY_SUBMODELS, {}) model_definition = self._serializer.data.get(KEY_MODEL) try: if KEY_COMPONENT_ID in model_definition: # The defined model is only one system system_id = model_definition[KEY_COMPONENT_ID] sub_component = RegisterOpenMDAOSystem.get_system(system_id) model.add_subsystem("system", sub_component, promotes=["*"]) else: # The defined model is a group self._parse_problem_table(model, model_definition) except FASTConfigurationBaseKeyBuildingError as err: log_err = err.__class__(err, KEY_MODEL) _LOGGER.error(log_err) raise log_err
def _parse_problem_table(self, group: om.Group, table: dict): """ Feeds provided *group*, using definition in provided TOML *table*. :param group: :param table: """ # assert isinstance(table, dict), "table should be a dictionary" for key, value in table.items(): if isinstance(value, dict): # value defines a sub-component if KEY_COMPONENT_ID in value: # It is a non-group component, that should be registered with its ID options = value.copy() identifier = options.pop(KEY_COMPONENT_ID) # Process option values that are relative paths conf_dirname = pth.dirname(self._conf_file) for name, option_value in options.items(): option_is_path = (name.endswith("file") or name.endswith("path") or name.endswith("dir") or name.endswith("directory") or name.endswith("folder")) if (isinstance(option_value, str) and option_is_path and not pth.isabs(option_value)): options[name] = pth.join(conf_dirname, option_value) sub_component = RegisterOpenMDAOSystem.get_system( identifier, options=options) group.add_subsystem(key, sub_component, promotes=["*"]) else: # It is a Group sub_component = group.add_subsystem(key, om.Group(), promotes=["*"]) try: self._parse_problem_table(sub_component, value) except FASTConfigurationBadOpenMDAOInstructionError as err: # There has been an error while parsing an attribute. # Error is relayed with key added for context raise FASTConfigurationBadOpenMDAOInstructionError( err, key) elif key == KEY_CONNECTION_ID and isinstance(value, list): # a list of dict currently defines only connections for connection_def in value: group.connect(connection_def["source"], connection_def["target"]) else: # value is an attribute of current component and will be literally interpreted try: setattr(group, key, _om_eval(str(value))) # pylint:disable=eval-used except Exception as err: raise FASTConfigurationBadOpenMDAOInstructionError( err, key, value)
def _get_detailed_system_list(): cell_list = [[ "AVAILABLE MODULE IDENTIFIERS\n============================" ]] for identifier in sorted(RegisterOpenMDAOSystem.get_provider_ids()): path = BundleLoader().get_factory_path(identifier) domain = RegisterOpenMDAOSystem.get_provider_domain(identifier) description = RegisterOpenMDAOSystem.get_provider_description( identifier) if description is None: description = "" # We remove OpenMDAO's native options from the description component = RegisterOpenMDAOSystem.get_system(identifier) component.options.undeclare("assembled_jac_type") component.options.undeclare("distributed") cell_content = ( " IDENTIFIER: %s\nPATH: %s\nDOMAIN: %s\nDESCRIPTION: %s\n" % (identifier, path, domain.value, tw.indent(tw.dedent(description), " "))) if len(list(component.options.items())) > 0: cell_content += component.options.to_table(fmt="grid") + "\n" cell_list.append([cell_content]) cell_list.append([ "AVAILABLE PROPULSION WRAPPER IDENTIFIERS\n========================================" ]) for identifier in sorted(RegisterPropulsion.get_provider_ids()): path = BundleLoader().get_factory_path(identifier) description = RegisterPropulsion.get_provider_description(identifier) if description is None: description = "" cell_content = " IDENTIFIER: %s\nPATH: %s\nDESCRIPTION: %s\n" % ( identifier, path, tw.indent(tw.dedent(description), " "), ) cell_list.append([cell_content]) return cell_list