From 0e6b2489c97878a848a486faabfa07895d1483ab Mon Sep 17 00:00:00 2001 From: Frode Helgetun Krogh <70878501+frodehk@users.noreply.github.com> Date: Tue, 7 May 2024 15:56:01 +0200 Subject: [PATCH] fix: ensure regularity is evaluated for all installations when only venting emitters (#468) * fix: ensure regularity is evaluated for all installations ECALC-1061 --- src/libecalc/application/graph_result.py | 7 +-- .../venting_emitters/venting_emitter_yaml.py | 11 +--- src/tests/libecalc/output/results/test_ltp.py | 50 +++++++++++++++++-- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/libecalc/application/graph_result.py b/src/libecalc/application/graph_result.py index a4c08b7619..da9813fe0f 100644 --- a/src/libecalc/application/graph_result.py +++ b/src/libecalc/application/graph_result.py @@ -1249,9 +1249,10 @@ def get_asset_result(self) -> libecalc.dto.result.EcalcModelResult: sub_components.append(obj) - # When only venting emitters are specified, without a generator set: the installation result is empty. - # Ensure that the installation regularity is found, even if only venting emitters are defined: - if not installation_results: + # When only venting emitters are specified, without a generator set: the installation result + # is empty for this installation. Ensure that the installation regularity is found, even if only + # venting emitters are defined for one installation: + if len(installation_results) < len(asset.installations): regularities = { installation.id: TimeSeriesFloat( values=TemporalExpression.evaluate( diff --git a/src/libecalc/fixtures/cases/venting_emitters/venting_emitter_yaml.py b/src/libecalc/fixtures/cases/venting_emitters/venting_emitter_yaml.py index aa7c23218e..e600812f1e 100644 --- a/src/libecalc/fixtures/cases/venting_emitters/venting_emitter_yaml.py +++ b/src/libecalc/fixtures/cases/venting_emitters/venting_emitter_yaml.py @@ -27,6 +27,7 @@ def venting_emitter_yaml_factory( emitter_types: List[str] = None, categories: List[str] = None, emission_keyword_name: str = "EMISSIONS", + installation_name: str = "minimal_installation", emission_factors: List[float] = None, oil_rates: List[float] = None, units_oil_rates: List[Unit] = None, @@ -46,14 +47,6 @@ def venting_emitter_yaml_factory( if emission_rates is None: emission_rates = [10] * len(names) - f""" - {create_venting_emitters_yaml( - categories=categories, rate_types=rate_types, emitter_names=names, emission_names=emission_names, - emission_rates=emission_rates, units=units, emission_keyword_name=emission_keyword_name, include_emitters=include_emitters, - emitter_types=emitter_types, oil_rates=oil_rates, emission_factors=emission_factors, units_oil_rates=units_oil_rates, - )} - """ - input_text = f""" FACILITY_INPUTS: - NAME: generator_energy_function @@ -69,7 +62,7 @@ def venting_emitter_yaml_factory( END: 2029-01-01 INSTALLATIONS: - - NAME: minimal_installation + - NAME: {installation_name} HCEXPORT: 0 FUEL: fuel CATEGORY: FIXED diff --git a/src/tests/libecalc/output/results/test_ltp.py b/src/tests/libecalc/output/results/test_ltp.py index 6a045972dd..8dccbd4d3f 100644 --- a/src/tests/libecalc/output/results/test_ltp.py +++ b/src/tests/libecalc/output/results/test_ltp.py @@ -296,7 +296,8 @@ def test_only_venting_emitters_no_fuelconsumers(): variables = dto.VariablesMap(time_vector=time_vector, variables={}) - dto_case = venting_emitter_yaml_factory( + # Installation with only venting emitters: + dto_case_emitters = venting_emitter_yaml_factory( emission_rates=[emission_rate], regularity=regularity, units=[Unit.KILO_PER_DAY], @@ -305,20 +306,61 @@ def test_only_venting_emitters_no_fuelconsumers(): include_emitters=True, include_fuel_consumers=False, names=["Venting emitter 1"], + installation_name="Venting emitter installation", path=Path(venting_emitters.__path__[0]), ) + venting_emitter_results = get_consumption( - model=dto_case.ecalc_model, variables=variables, time_vector=time_vector_yearly + model=dto_case_emitters.ecalc_model, variables=variables, time_vector=time_vector_yearly ) - # Verify that eCalc, is not failing in get_asset_result, with only venting emitters - + # Verify that eCalc is not failing in get_asset_result with only venting emitters - # when installation result is empty, i.e. with no genset and fuel consumers: - assert isinstance(get_consumption_asset_result(model=dto_case.ecalc_model, variables=variables), EcalcModelResult) + assert isinstance( + get_consumption_asset_result(model=dto_case_emitters.ecalc_model, variables=variables), EcalcModelResult + ) # Verify correct emissions: emissions_ch4 = get_sum_ltp_column(venting_emitter_results, installation_nr=0, ltp_column_nr=0) assert emissions_ch4 == (emission_rate / 1000) * 365 * regularity + # Installation with only fuel consumers: + dto_case_fuel = venting_emitter_yaml_factory( + emission_rates=[emission_rate], + regularity=regularity, + units=[Unit.KILO_PER_DAY], + emission_names=["ch4"], + rate_types=[RateType.STREAM_DAY], + include_emitters=False, + include_fuel_consumers=True, + names=["Venting emitter 1"], + installation_name="Fuel consumer installation", + path=Path(venting_emitters.__path__[0]), + ) + + asset_multi_installations = dto.Asset( + name="Multi installations", + installations=[dto_case_emitters.ecalc_model.installations[0], dto_case_fuel.ecalc_model.installations[0]], + ) + + # Verify that eCalc is not failing in get_asset_result, with only venting emitters - + # when installation result is empty for one installation, i.e. with no genset and fuel consumers. + # Include asset with two installations, one with only emitters and one with only fuel consumers - + # ensure that get_asset_result returns a result: + + assert isinstance( + get_consumption_asset_result(model=asset_multi_installations, variables=variables), EcalcModelResult + ) + + asset_ltp_result = get_consumption( + model=asset_multi_installations, variables=variables, time_vector=time_vector_yearly + ) + # Check that the results are the same: For the case with only one installation (only venting emitters), + # compared to the multi-installation case with two installations. The fuel-consumer installation should + # give no CH4-contribution (only CO2) + emissions_ch4_asset = get_sum_ltp_column(asset_ltp_result, installation_nr=0, ltp_column_nr=0) + assert emissions_ch4 == emissions_ch4_asset + def test_no_emitters_or_fuelconsumers(): """