def test_calculation_of_lcoe_of_asset_total_flow_is_0(): """Tests if LCOE is set to None with TOTAL_FLOW of asset is 0""" for group in [ENERGY_CONVERSION, ENERGY_STORAGE]: for asset in dict_values[group]: E2.lcoe_assets(dict_values[group][asset], group) assert dict_values[ENERGY_CONVERSION]["inverter"][LCOE_ASSET][VALUE] is 0 assert dict_values[ENERGY_STORAGE]["battery_2"][LCOE_ASSET][VALUE] is 0
def test_calculation_of_lcoe_asset_storage_flow_not_0_provider_flow_not_0(): """Tests whether the LCOE is correctly calculated for each asset in the different asset groups""" for group in [ENERGY_PRODUCTION, ENERGY_CONSUMPTION, ENERGY_STORAGE]: for asset in dict_values[group]: E2.lcoe_assets(dict_values[group][asset], group) assert dict_values[ENERGY_PRODUCTION]["PV"][LCOE_ASSET][ VALUE] == exp_lcoe_pv assert (dict_values[ENERGY_CONSUMPTION]["demand"][LCOE_ASSET][VALUE] == exp_lcoe_demand) assert (dict_values[ENERGY_STORAGE]["battery_1"][LCOE_ASSET][VALUE] == exp_lcoe_battery_1) for component in [INPUT_POWER, OUTPUT_POWER, STORAGE_CAPACITY]: assert LCOE_ASSET in dict_values[ENERGY_STORAGE]["battery_1"][ component]
def test_all_cost_info_parameters_added_to_dict_asset(): """Tests whether the function get_costs is adding all the calculated costs to dict_asset.""" E2.get_costs(dict_asset, dict_economic) # Note: The valid calculation of the costs is tested with test_benchmark_KPI.py, Test_Economic_KPI.test_benchmark_Economic_KPI_C2_E2() for k in ( COST_DISPATCH, COST_OM, COST_TOTAL, COST_OPERATIONAL_TOTAL, ANNUITY_TOTAL, ANNUITY_OM, ): assert ( k in dict_asset ), f"Attribute {k} is not in the asset dictionary, eventhough it should have been added."
def test_calculate_total_asset_costs_over_lifetime(): investment_costs = 300 om_costs = 200 total = E2.calculate_total_asset_costs_over_lifetime( costs_investment=investment_costs, cost_operational_expenditures=om_costs) assert ( total == investment_costs + om_costs ), f"The total costs are with {total} not equal to the sum of the investment ({investment_costs}) and OM ({om_costs}) costs."
def test_calculate_operation_and_management_expenditures(): installed_capacity = 10 optimized_add_capacity = 10 specific_om_cost = 5 operation_and_management_expenditures = E2.calculate_operation_and_management_expenditures( specific_om_cost=specific_om_cost, installed_capacity=installed_capacity, optimized_add_capacity=optimized_add_capacity, ) assert operation_and_management_expenditures == specific_om_cost * ( installed_capacity + optimized_add_capacity ), f"With {operation_and_management_expenditures}, the OM costs are not equal to the sum of the capacities ({installed_capacity+optimized_add_capacity}) times the specific costs ({specific_om_cost})."
def test_calculate_costs_replacement(): """Tests whether replacement costs both for existing and future capacities were calculated correctly""" installed_capacity = 1 specific_replacement_costs_of_installed_cap = 5 optimized_add_capacity = 10 specific_replacement_costs_of_optimized_cap = 10 cost_replacement = E2.calculate_costs_replacement( specific_replacement_of_initial_capacity= specific_replacement_costs_of_installed_cap, specific_replacement_of_optimized_capacity= specific_replacement_costs_of_optimized_cap, initial_capacity=installed_capacity, optimized_capacity=optimized_add_capacity, ) assert ( cost_replacement == specific_replacement_costs_of_installed_cap * installed_capacity + specific_replacement_costs_of_optimized_cap * optimized_add_capacity ), f"With {cost_replacement}, the total replacement costs are not equal to the sum of the replacement costs of each pre-installed ({specific_replacement_costs_of_installed_cap * installed_capacity}) and additional capacity ({specific_replacement_costs_of_optimized_cap * optimized_add_capacity})."
def test_calculate_annual_dispatch_expenditures_pd_Series(): dispatch_price = pd.Series([1, 2, 3]) dispatch_expenditure = E2.calculate_dispatch_expenditures( dispatch_price, flow, asset) assert dispatch_expenditure == 6
def test_all_list_in_dict_fails_due_to_not_included_keys(): """Tests whether looking for list items in dict_asset is plausible.""" list_false = [AGE_INSTALLED, OPTIMIZED_ADD_CAP] with pytest.raises(E2.MissingParametersForEconomicEvaluation): boolean = E2.all_list_in_dict(dict_asset, list_false) assert boolean is False
def test_all_list_in_dict_passes_as_all_keys_included(): """Tests whether looking for list items in dict_asset is plausible.""" list_true = [ANNUAL_TOTAL_FLOW, OPTIMIZED_ADD_CAP] boolean = E2.all_list_in_dict(dict_asset, list_true) assert boolean is True
def test_calculate_annual_dispatch_expenditures_str_error(): """Tests if a error is raised when a list with a nested list and a str value is provided as a dispatch price.""" with pytest.raises(TypeError): dispatch_expenditure = E2.calculate_dispatch_expenditures( dispatch_price=[1, ["hi", 2]], flow=flow, asset=asset)
def test_calculate_annual_dispatch_expenditures_nested_list(): dispatch_expenditure = E2.calculate_dispatch_expenditures( dispatch_price=[1, [1, 2]], flow=flow, asset=asset) assert ( dispatch_expenditure == 3 + 3 + 6 ), f"The total dispatch expenditures ({dispatch_expenditure}) are not equal to the expected value if the dispatch price is provided as a list with a nested list. "
def test_calculate_annual_dispatch_expenditures_list_pd_series(): dispatch_expenditure = E2.calculate_dispatch_expenditures( dispatch_price=[1, pd.Series([1, 2, 3])], flow=flow, asset=asset) assert ( dispatch_expenditure == 9 ), f"The total dispatch expenditures ({dispatch_expenditure}) are not equal to the expected value if the dispatch price is provided as a list with a nested pd.Series. "
def test_calculate_annual_dispatch_expenditures_list_scalars(): dispatch_expenditure = E2.calculate_dispatch_expenditures( dispatch_price=[1, 1], flow=flow, asset=asset) assert ( dispatch_expenditure == 6 ), f"The total dispatch expenditures ({dispatch_expenditure}) are not equal to the expected value if the dispatch price is provided as a list. "
def test_calculate_annual_dispatch_expenditures_float(): dispatch_expenditure = E2.calculate_dispatch_expenditures(dispatch_price=1, flow=flow, asset=asset) assert dispatch_expenditure == 3
def test_calculate_total_operational_expenditures(): total_operational_expenditures = E2.calculate_total_operational_expenditures( operation_and_management_expenditures=100, dispatch_expenditures=500) assert total_operational_expenditures == 600
def test_calculate_total_capital_costs(): total_capital_expenditure = E2.calculate_total_capital_costs( upfront=300, replacement=100) assert total_capital_expenditure == 400
def test_calculate_costs_upfront_investment(): costs = E2.calculate_costs_upfront_investment(specific_cost=100, capacity=5, development_costs=200) assert costs == 700
def evaluate_dict(dict_values, results_main, results_meta): """ Parameters ---------- dict_values: dict simulation parameters results_main: DataFrame oemof simulation results as output by processing.results() results_meta: DataFrame oemof simulation meta information as output by processing.meta_results() Returns ------- """ dict_values.update( { KPI: { KPI_COST_MATRIX: pd.DataFrame(columns=KPI_COST_MATRIX_ENTRIES), KPI_SCALAR_MATRIX: pd.DataFrame(columns=KPI_SCALAR_MATRIX_ENTRIES), KPI_SCALARS_DICT: {}, } } ) bus_data = {} # Store all information related to busses in bus_data for bus in dict_values[ENERGY_BUSSES]: # Read all energy flows from busses bus_data.update({bus: solph.views.node(results_main, bus)}) logging.info("Evaluating optimized capacities and dispatch.") # Evaluate timeseries and store to a large DataFrame for each bus: E1.get_timeseries_per_bus(dict_values, bus_data) # Store all information related to storages in bus_data, as storage capacity acts as a bus for storage in dict_values[ENERGY_STORAGE]: bus_data.update( { dict_values[ENERGY_STORAGE][storage][LABEL]: solph.views.node( results_main, dict_values[ENERGY_STORAGE][storage][LABEL], ) } ) E1.get_storage_results( dict_values[SIMULATION_SETTINGS], bus_data[dict_values[ENERGY_STORAGE][storage][LABEL]], dict_values[ENERGY_STORAGE][storage], ) for storage_item in [STORAGE_CAPACITY, INPUT_POWER, OUTPUT_POWER]: E2.get_costs( dict_values[ENERGY_STORAGE][storage][storage_item], dict_values[ECONOMIC_DATA], ) E2.lcoe_assets(dict_values[ENERGY_STORAGE][storage], ENERGY_STORAGE) for storage_item in [STORAGE_CAPACITY, INPUT_POWER, OUTPUT_POWER]: store_result_matrix( dict_values[KPI], dict_values[ENERGY_STORAGE][storage][storage_item] ) if ( dict_values[ENERGY_STORAGE][storage][INPUT_BUS_NAME] in dict_values[OPTIMIZED_FLOWS].keys() ) or ( dict_values[ENERGY_STORAGE][storage][OUTPUT_BUS_NAME] in dict_values[OPTIMIZED_FLOWS].keys() ): bus_name = dict_values[ENERGY_STORAGE][storage][INPUT_BUS_NAME] timeseries_name = ( dict_values[ENERGY_STORAGE][storage][LABEL] + " (" + str( round( dict_values[ENERGY_STORAGE][storage][STORAGE_CAPACITY][ OPTIMIZED_ADD_CAP ][VALUE], 1, ) ) + dict_values[ENERGY_STORAGE][storage][STORAGE_CAPACITY][ OPTIMIZED_ADD_CAP ][UNIT] + ") SOC" ) dict_values[OPTIMIZED_FLOWS][bus_name][timeseries_name] = dict_values[ ENERGY_STORAGE ][storage]["timeseries_soc"] for group in [ENERGY_CONVERSION, ENERGY_PRODUCTION, ENERGY_CONSUMPTION]: for asset in dict_values[group]: E1.get_results( settings=dict_values[SIMULATION_SETTINGS], bus_data=bus_data, dict_asset=dict_values[group][asset], asset_group=group, ) E2.get_costs(dict_values[group][asset], dict_values[ECONOMIC_DATA]) E2.lcoe_assets(dict_values[group][asset], group) store_result_matrix(dict_values[KPI], dict_values[group][asset]) logging.info("Evaluating key performance indicators of the system") E3.all_totals(dict_values) E3.total_demand_and_excess_each_sector(dict_values) E3.add_total_feedin_electricity_equivaluent(dict_values) E3.add_levelized_cost_of_energy_carriers(dict_values) E3.add_total_renewable_and_non_renewable_energy_origin(dict_values) E3.add_renewable_share_of_local_generation(dict_values) E3.add_renewable_factor(dict_values) # E3.add_degree_of_sector_coupling(dict_values) feature not finished E3.add_onsite_energy_fraction(dict_values) E3.add_onsite_energy_matching(dict_values) E3.add_degree_of_autonomy(dict_values) # Tests and checks logging.info("Running validity checks.") E4.minimal_renewable_share_test(dict_values) E4.detect_excessive_excess_generation_in_bus(dict_values)
def test_calculate_annual_dispatch_expenditures_else(): """Test if error is raised if the dispatch price is provided as a str.""" with pytest.raises(TypeError): E2.calculate_dispatch_expenditures("str", flow, asset)