def load_plugins(): """ Loads declared plugins. """ for entry_point in iter_entry_points(MODEL_PLUGIN_ID): plugin_name = entry_point.name module_name = entry_point.module_name _LOGGER.info("Loading FAST-OAD plugin %s", plugin_name) BundleLoader().explore_folder(module_name, is_package=True) Variable.read_variable_descriptions(module_name)
def load_plugins(): """ Loads declared plugins. """ for entry_point in iter_entry_points(MODEL_PLUGIN_ID): plugin_name = entry_point.name module_name = entry_point.module_name _recursive_load(module_name) _LOGGER.info("Loaded FAST-OAD plugin %s", plugin_name) Variable.read_variable_descriptions(module_name)
def _load_models(cls, plugin_definition: PluginDefinition): """Loads models from plugin.""" if SubPackageNames.MODELS in plugin_definition.subpackages: _LOGGER.debug(" Loading models") BundleLoader().explore_folder( plugin_definition.subpackages[SubPackageNames.MODELS], is_package=True ) Variable.read_variable_descriptions( plugin_definition.subpackages[SubPackageNames.MODELS] )
def test_register_checks_as_decorator(cleanup): log_file_path = pth.join(RESULTS_FOLDER_PATH, "log4.txt") set_logger_file(log_file_path) @ValidityDomainChecker({"input1": (1.0, 5.0), "output2": (300.0, 500.0)}, "main.dec") class Comp1(om.ExplicitComponent): def setup(self): self.add_input("input1", 0.5, units="km") self.add_output("output1", 150.0, units="km/h", upper=130.0) self.add_output("output2", 200.0, units="K", lower=0.0) self.add_output("output3", 1000.0, units="kg", lower=0.0, upper=5000.0) comp = Comp1() # Just checking there is no side effect. VariableList.from_system() uses # setup(), even if it is made to have no effect, and ValidityDomainChecker # modifies setup(), so is is worth checking. variables = VariableList.from_system(comp) assert len(variables) == 4 # Now for the real test # We test that upper and lower bounds are retrieved from OpenMDAO component, # overwritten when required and that units are correctly taken into account. comp.setup() variables = VariableList( [ Variable("input1", value=3.0, units="m"), Variable("output1", value=40.0, units="m/s"), Variable("output2", value=310.0, units="degC"), Variable("output3", value=6.0, units="t"), ] ) records = ValidityDomainChecker.check_variables(variables) assert [ ( rec.variable_name, rec.status, rec.limit_value, rec.value, rec.source_file, rec.logger_name, ) for rec in records ] == [ ("input1", ValidityStatus.TOO_LOW, 1.0, 3.0, __file__, "main.dec"), ("output1", ValidityStatus.TOO_HIGH, 130.0, 40.0, __file__, "main.dec"), ("output2", ValidityStatus.TOO_HIGH, 500.0, 310.0, __file__, "main.dec"), ("output3", ValidityStatus.TOO_HIGH, 5000.0, 6.0, __file__, "main.dec"), ] ValidityDomainChecker.log_records(records) with open(log_file_path) as log_file: assert len(log_file.readlines()) == 4
def test_plugins(with_dummy_plugins): FastoadLoader._loaded = True # Ensures next instantiation will NOT trigger reloading # Before FastoadLoader.load(), services are not registered with pytest.raises(FastBundleLoaderUnknownFactoryNameError): declared_dummy_1 = RegisterService.get_provider( "test.plugin.declared.1") with pytest.raises(FastBundleLoaderUnknownFactoryNameError): decorated_dummy_1 = RegisterService.get_provider( "test.plugin.decorated.1") FastoadLoader._loaded = False # Ensures next instantiation will trigger reloading dist1_definition = FastoadLoader( ).distribution_plugin_definitions["dummy-dist-1"] assert "models" not in dist1_definition["test_plugin_1"].subpackages assert "notebooks" not in dist1_definition["test_plugin_1"].subpackages assert "models" not in dist1_definition["test_plugin_4"].subpackages assert "configurations" not in dist1_definition[ "test_plugin_4"].subpackages dist2_definition = FastoadLoader( ).distribution_plugin_definitions["dummy-dist-2"] assert ( dist2_definition["test_plugin_3"].subpackages[SubPackageNames.MODELS] == "tests.dummy_plugins.dist_2.dummy_plugin_3.models") assert "notebooks" not in dist2_definition["test_plugin_3"].subpackages assert (dist2_definition["test_plugin_3"].subpackages[ SubPackageNames.CONFIGURATIONS] == "tests.dummy_plugins.dist_2.dummy_plugin_3.configurations") declared_dummy_1 = RegisterService.get_provider("test.plugin.declared.1") assert declared_dummy_1.my_class() == "DeclaredDummy1" declared_dummy_2 = RegisterService.get_provider("test.plugin.declared.2") assert declared_dummy_2.my_class() == "DeclaredDummy2" decorated_dummy_1 = RegisterService.get_provider("test.plugin.decorated.1") assert decorated_dummy_1.my_class() == "DecoratedDummy1" decorated_dummy_2 = RegisterService.get_provider("test.plugin.decorated.2") assert decorated_dummy_2.my_class() == "DecoratedDummy2" # This one is in a subpackage decorated_dummy_3 = RegisterService.get_provider("test.plugin.decorated.3") assert decorated_dummy_3.my_class() == "DecoratedDummy3" # Checking variable description. assert Variable("dummy:variable").description == "Some dummy variable."
def cleanup(): rmtree(RESULTS_FOLDER_PATH, ignore_errors=True) # Need to clean up variable descriptions because it is manipulated in other tests. Variable.read_variable_descriptions(pth.dirname(fastoad.models.__file__), update_existing=False)
def test_write_outputs(): problem = FASTOADProblem() problem.model.add_subsystem("sellar", Sellar(), promotes=["*"]) problem.output_file_path = pth.join(RESULTS_FOLDER_PATH, "output.xml") problem.setup() problem.write_outputs() variables = VariableIO(problem.output_file_path).read() assert variables == [ Variable(name="f", value=1.0), Variable(name="g1", value=1.0), Variable(name="g2", value=1.0), Variable(name="x", value=2), Variable(name="y2", value=1.0), Variable(name="z", value=[5.0, 2.0], units="m**2"), ] problem.run_model() problem.write_outputs() variables = VariableIO(problem.output_file_path).read() assert variables == [ Variable(name="f", value=32.569100892077444), Variable(name="g1", value=-23.409095627564167), Variable(name="g2", value=-11.845478137832359), Variable(name="x", value=2), Variable(name="y2", value=12.154521862167641), Variable(name="z", value=[5.0, 2.0], units="m**2"), ]
def test_register_checks_instantiation(cleanup): ValidityDomainChecker( { "var_with_upper_and_lower": (-1.0, 10.0), "var_with_lower": (-10.0, None), "var_with_upper": (None, 5.0), }, "main.logger1", ) # Now registering is done through instantiation, and with another logger ValidityDomainChecker( {"var_with_upper_and_lower": (-3.0, 5.0), "var_with_lower": (0.0, None)}, "main.logger2" ) # Third call with same logger as the first one ValidityDomainChecker({"other_var": (-10.0, 1.0)}, "main.logger1") # Check 1 -------------------------------------------------------------------------------------- log_file_path = pth.join(RESULTS_FOLDER_PATH, "log1.txt") set_logger_file(log_file_path) variables = VariableList( [ Variable("var_with_upper_and_lower", value=-2.0, units="m"), # too low for logger1 Variable("var_with_lower", value=-1.0), # too low for logger2 Variable("var_with_upper", value=10.0), # too high, only for logger1 Variable("other_var", value=1.1), # too high, only for logger1 (second registering) Variable("unbound_var", value=42.0), ] ) records = ValidityDomainChecker.check_variables(variables) assert [ ( rec.variable_name, rec.status, rec.limit_value, rec.value, rec.source_file, rec.logger_name, ) for rec in records ] == [ ("var_with_upper_and_lower", ValidityStatus.TOO_LOW, -1.0, -2.0, __file__, "main.logger1"), ("var_with_upper_and_lower", ValidityStatus.OK, None, -2.0, __file__, "main.logger2"), ("var_with_lower", ValidityStatus.OK, None, -1.0, __file__, "main.logger1"), ("var_with_lower", ValidityStatus.TOO_LOW, 0.0, -1.0, __file__, "main.logger2"), ("var_with_upper", ValidityStatus.TOO_HIGH, 5.0, 10.0, __file__, "main.logger1"), ("other_var", ValidityStatus.TOO_HIGH, 1.0, 1.1, __file__, "main.logger1"), ] ValidityDomainChecker.log_records(records) with open(log_file_path) as log_file: assert len(log_file.readlines()) == 4 # Check 2 -------------------------------------------------------------------------------------- log_file_path = pth.join(RESULTS_FOLDER_PATH, "log2.txt") set_logger_file(log_file_path) variables = VariableList( [ Variable("other_var", value=-11.0), # too low, only for logger1 (second registering) Variable("var_with_lower", value=-15.0), # too low for logger1 and logger2 Variable("var_with_upper", value=0.0), # Ok Variable("unbound_var", value=1e42), Variable("var_with_upper_and_lower", value=7.0), # too high for logger2 ] ) records = ValidityDomainChecker.check_variables(variables) assert [ ( rec.variable_name, rec.status, rec.limit_value, rec.value, rec.source_file, rec.logger_name, ) for rec in records ] == [ ("other_var", ValidityStatus.TOO_LOW, -10.0, -11.0, __file__, "main.logger1"), ("var_with_lower", ValidityStatus.TOO_LOW, -10.0, -15.0, __file__, "main.logger1"), ("var_with_lower", ValidityStatus.TOO_LOW, 0.0, -15.0, __file__, "main.logger2"), ("var_with_upper", ValidityStatus.OK, None, 0.0, __file__, "main.logger1"), ("var_with_upper_and_lower", ValidityStatus.OK, None, 7.0, __file__, "main.logger1"), ("var_with_upper_and_lower", ValidityStatus.TOO_HIGH, 5.0, 7.0, __file__, "main.logger2"), ] ValidityDomainChecker.log_records(records) with open(log_file_path) as log_file: assert len(log_file.readlines()) == 4 # Check 3 -------------------------------------------------------------------------------------- log_file_path = pth.join(RESULTS_FOLDER_PATH, "log3.txt") set_logger_file(log_file_path) variables = VariableList( [ Variable("var_with_upper_and_lower", value=1.0), # Ok Variable("other_var", value=-5.0), # Ok Variable("unbound_var", value=-1e42), Variable("var_with_lower", value=1.0), # Ok ] ) records = ValidityDomainChecker.check_variables(variables) assert [ ( rec.variable_name, rec.status, rec.limit_value, rec.value, rec.source_file, rec.logger_name, ) for rec in records ] == [ ("var_with_upper_and_lower", ValidityStatus.OK, None, 1.0, __file__, "main.logger1"), ("var_with_upper_and_lower", ValidityStatus.OK, None, 1.0, __file__, "main.logger2"), ("other_var", ValidityStatus.OK, None, -5.0, __file__, "main.logger1"), ("var_with_lower", ValidityStatus.OK, None, 1.0, __file__, "main.logger1"), ("var_with_lower", ValidityStatus.OK, None, 1.0, __file__, "main.logger2"), ] ValidityDomainChecker.log_records(records) with open(log_file_path) as log_file: assert len(log_file.readlines()) == 0
def test_write_outputs(): problem = FASTOADProblem() problem.model.add_subsystem("sellar", Sellar(), promotes=["*"]) problem.output_file_path = pth.join(RESULTS_FOLDER_PATH, "output.xml") problem.setup() problem.write_outputs() variables = VariableIO(problem.output_file_path).read() assert variables == [ Variable(name="f", val=1.0), Variable(name="g1", val=1.0), Variable(name="g2", val=1.0), Variable(name="x", val=2.0), Variable(name="y2", val=1.0), Variable(name="z", val=[np.nan, np.nan], units="m**2"), ] problem["x"] = 2.0 problem["z"] = [ 5.0, 2.0, ] # Since version 3.17 of OpenMDAO, the np.nan input definition of z is chosen. problem.run_model() problem.write_outputs() variables = VariableIO(problem.output_file_path).read() assert variables == [ Variable(name="f", val=32.569100892077444), Variable(name="g1", val=-23.409095627564167), Variable(name="g2", val=-11.845478137832359), Variable(name="x", val=2.0), Variable(name="y2", val=12.154521862167641), Variable(name="z", val=[5.0, 2.0], units="m**2"), ]