def test_simplest_case(self, get_scenario): """One scenario only """ elec_scenario = get_scenario sos_model = SosModel('simple') sos_model.add_model(elec_scenario) data_handle = get_data_handle(sos_model) sos_model.simulate(data_handle)
def test_default_parameter_passing_(self, get_empty_sector_model): """Tests that default values for global parameters are passed to all models, and others default values only passed into the intended models. """ sos_model_param = { 'name': 'sos_model_param', 'description': 'A global parameter passed to all contained models', 'absolute_range': (0, 100), 'suggested_range': (3, 10), 'default_value': 3, 'units': '%' } sos_model = SosModel('global') sos_model.add_parameter(sos_model_param) sector_model = get_empty_sector_model('source_model') # Patch the sector model so that it returns the calling arguments sector_model.simulate = lambda _, y: {'sm1': y} sos_model.add_model(sector_model) assert sos_model.simulate(2010) == {'sm1': {'sos_model_param': 3}} sector_model.add_parameter({ 'name': 'sector_model_param', 'description': 'Some meaningful text', 'absolute_range': (0, 100), 'suggested_range': (3, 10), 'default_value': 3, 'units': '%' }) assert sos_model.simulate(2010) == { 'sm1': { 'sector_model_param': 3, 'sos_model_param': 3 } } sector_model_2 = get_empty_sector_model('another') sector_model_2.simulate = lambda _, y: {'sm2': y} sos_model.add_model(sector_model_2) assert sos_model.simulate(2010) == { 'sm1': { 'sector_model_param': 3, 'sos_model_param': 3 }, 'sm2': { 'sos_model_param': 3 } }
def test_simulate_data_not_present(self, get_sector_model): SectorModel = get_sector_model """Raise a NotImplementedError if an input is defined but no dependency links it to a data source """ sos_model = SosModel('test') model = SectorModel('test_model') model.add_input('input', Mock(), Mock(), 'units') sos_model.add_model(model) data_handle = get_data_handle(sos_model) with raises(NotImplementedError): sos_model.simulate(data_handle)
def test_simplest_case(self, get_scenario): """One scenario only """ elec_scenario = get_scenario sos_model = SosModel('simple') sos_model.add_model(elec_scenario) actual = sos_model.simulate(2010) expected = { 'electricity_demand_scenario': { 'electricity_demand_output': np.array([[123]]) } } assert actual == expected
def test_sector_model_one_input(self, get_energy_sector_model, get_scenario): elec_scenario = get_scenario energy_model = get_energy_sector_model energy_model.add_dependency(elec_scenario, 'electricity_demand_output', 'electricity_demand_input') sos_model = SosModel('blobby') sos_model.add_model(elec_scenario) sos_model.add_model(energy_model) data_handle = get_data_handle(sos_model) results = sos_model.simulate(data_handle) expected = np.array([[100.737]]) actual = results.get_results('fluffiness', 'energy_sector_model') np.testing.assert_allclose(actual, expected, rtol=1e-5)
def test_loop(self, get_energy_sector_model, get_water_sector_model): """Fails because no functionality to deal with loops """ energy_model = get_energy_sector_model water_model = get_water_sector_model sos_model = SosModel('energy_water_model') water_model.add_dependency(energy_model, 'fluffiness', 'fluffyness') energy_model.add_dependency(water_model, 'electricity_demand', 'electricity_demand_input') sos_model.add_model(water_model) sos_model.add_model(energy_model) assert energy_model.model_inputs.names == ['electricity_demand_input'] assert water_model.model_inputs.names == ['fluffyness'] assert sos_model.model_inputs.names == [] assert energy_model.free_inputs.names == [] assert water_model.free_inputs.names == [] assert sos_model.free_inputs.names == [] sos_model.check_dependencies() graph = sos_model.dependency_graph assert (water_model, energy_model) in graph.edges() assert (energy_model, water_model) in graph.edges() modelset = ModelSet([water_model, energy_model], sos_model) actual = modelset.guess_results(water_model, 2010, {}) expected = {'electricity_demand': np.array([1.])} # assert actual == expected sos_model.max_iterations = 100 results = sos_model.simulate(2010) expected = np.array([[0.13488114]], dtype=np.float) actual = results['energy_sector_model']['fluffiness'] np.testing.assert_allclose(actual, expected, rtol=1e-5) expected = np.array([[0.16469004]], dtype=np.float) actual = results['water_supply_model']['electricity_demand'] np.testing.assert_allclose(actual, expected, rtol=1e-5)
def test_loop(self, get_energy_sector_model, get_water_sector_model): """Fails because no functionality to deal with loops """ energy_model = get_energy_sector_model water_model = get_water_sector_model sos_model = SosModel('energy_water_model') water_model.add_dependency(energy_model, 'fluffiness', 'fluffyness') energy_model.add_dependency(water_model, 'electricity_demand', 'electricity_demand_input') sos_model.add_model(water_model) sos_model.add_model(energy_model) assert energy_model.inputs.names == ['electricity_demand_input'] assert water_model.inputs.names == ['fluffyness'] assert sos_model.inputs.names == [] assert energy_model.free_inputs.names == [] assert water_model.free_inputs.names == [] assert sos_model.free_inputs.names == [] sos_model.check_dependencies() graph = sos_model.dependency_graph assert (water_model, energy_model) in graph.edges() assert (energy_model, water_model) in graph.edges() sos_model.max_iterations = 100 data_handle = get_data_handle(sos_model) results = sos_model.simulate(data_handle) expected = np.array([[0.13488114]], dtype=np.float) actual = results.get_results('fluffiness', model_name='energy_sector_model', modelset_iteration=35) np.testing.assert_allclose(actual, expected, rtol=1e-5) expected = np.array([[0.16469004]], dtype=np.float) actual = results.get_results('electricity_demand', model_name='water_supply_model', modelset_iteration=35) np.testing.assert_allclose(actual, expected, rtol=1e-5)
def test_sector_model_one_input(self, get_energy_sector_model, get_scenario): elec_scenario = get_scenario energy_model = get_energy_sector_model energy_model.add_dependency(elec_scenario, 'electricity_demand_output', 'electricity_demand_input') sos_model = SosModel('blobby') sos_model.add_model(elec_scenario) sos_model.add_model(energy_model) actual = sos_model.simulate(2010) expected = { 'energy_sector_model': { 'fluffiness': np.array([[100.737]]) }, 'electricity_demand_scenario': { 'electricity_demand_output': np.array([[123]]) } } assert actual == expected
def test_composite_nested_sos_model(self, get_sector_model): """System of systems example with two nested SosModels, two Scenarios and one SectorModel. One dependency is defined at the SectorModel level, another at the lower SosModel level """ SectorModel = get_sector_model elec_scenario = ScenarioModel('electricity_demand_scenario') elec_scenario.add_output('electricity_demand_output', Mock(), Mock(), 'unit') energy_model = SectorModel('energy_sector_model') energy_model.add_input( 'electricity_demand_input', Mock(), Mock(), 'unit') energy_model.add_input('fluffiness_input', Mock(), Mock(), 'unit') energy_model.add_output('cost', Mock(), Mock(), 'unit') energy_model.add_output('fluffyness', Mock(), Mock(), 'unit') def energy_function(timestep, input_data): """Mimics the running of a sector model """ results = {} demand = input_data['electricity_demand_input'] fluff = input_data['fluffiness_input'] results['cost'] = demand * 1.2894 results['fluffyness'] = fluff * 22 return results energy_model.simulate = energy_function energy_model.add_dependency(elec_scenario, 'electricity_demand_output', 'electricity_demand_input') sos_model_lo = SosModel('lower') sos_model_lo.add_model(elec_scenario) sos_model_lo.add_model(energy_model) fluf_scenario = ScenarioModel('fluffiness_scenario') fluf_scenario.add_output('fluffiness', Mock(), Mock(), 'unit') # fluf_scenario.add_data('fluffiness', np.array([[[12]]]), [2010]) assert sos_model_lo.free_inputs.names == ['fluffiness_input'] sos_model_lo.add_dependency(fluf_scenario, 'fluffiness', 'fluffiness_input') assert sos_model_lo.inputs.names == [] sos_model_high = SosModel('higher') sos_model_high.add_model(sos_model_lo) sos_model_high.add_model(fluf_scenario) data_handle = get_data_handle(sos_model_high) actual = sos_model_high.simulate(data_handle) expected = { 'fluffiness_scenario': { 'fluffiness': 12 }, 'lower': { 'electricity_demand_scenario': { 'electricity_demand_output': 123 }, 'energy_sector_model': { 'cost': 158.5962, 'fluffyness': 264 } } } assert actual == expected