Conversation
|
@KobusVanRooyen Hi Kobus. I made a cost calculation test as general as possible. This function calculates the cost for assets that we use in heat networks. Assets like electrolyzer, pump, ... are not included yet. I did not incorporate influence of pumpower cost and electricity price profile yet. Shall I also include those? What do you think |
# Conflicts: # tests/test_cold_demand.py # tests/test_elec_boiler.py # tests/test_end_scenario_sizing.py # tests/test_gas_boiler.py # tests/test_gas_electricity.py
|
|
||
| hp_id = name_to_id_map["HeatPump_b97e"] | ||
|
|
||
| cost_calculation_test(heat_problem, results) |
There was a problem hiding this comment.
- Will this test still pass if the _variable_operational_cost and parameters[f"{hp_id}.variable_operational_cost_coefficient"] might be zero for some reason?
- Based on the question above-> what about adding a hard check in the test case that one expects results[f"{hp_id}__variable_operational_cost"] to be > then .... (some sensible/large number and not 0).
- Some hard coded check like this will be needed in each test case where it is expected that a value should exist even if cost_calculation_test(heat_problem, results) is used. What do you think?
There was a problem hiding this comment.
Yes. This is a good point. I will add additional check to all tests (if needed) to ensure regarding cost component is non zero (larger than a large enough positive value)
| Checks: | ||
| 1. utils test: demand_matching_test, energy_conservation_test, heat_to_discharge_test, | ||
| electric_power_conservation_test, gas_pipes_head_loss_test | ||
| 1. utils test: cost_calculation_test, demand_matching_test, energy_conservation_test, |
There was a problem hiding this comment.
Previously the TCO was checked, an not not anymore?
| 2. demand is matched | ||
| 3. energy conservation in the network | ||
| 4. heat to discharge | ||
| 5. energy conservation over the heat and electricity commodity |
There was a problem hiding this comment.
why has item 5 been added? It is already mentioned in item 3?
There was a problem hiding this comment.
actually that line was refering to the followign check i the test: np.testing.assert_array_less(0.0, results[f"{e_boiler_id}.Heat_source"])
np.testing.assert_allclose(
parameters[f"{e_boiler_id}.efficiency"] * results[f"{e_boiler_id}.Power_consumed"],
results[f"{e_boiler_id}.Heat_source"],
)
However, you are right that item 3 is already hinting the same. Now I removed item 5
| 2. demand is matched | ||
| 3. energy conservation in the network | ||
| 4. heat to discharge | ||
| 5. energy conservation over the heat and electricity commodity |
There was a problem hiding this comment.
why has item 5 been added? It is already mentioned in item 3?
There was a problem hiding this comment.
it should be "electric_power_conservation_test". now updated
| parameters = heat_problem.parameters(0) | ||
| name_to_id_map = heat_problem.esdl_asset_name_to_id_map | ||
|
|
||
| cost_calculation_test(heat_problem, results) |
There was a problem hiding this comment.
checks needed before the function call to make sure the specific cost items exists (> than sensible value)
There was a problem hiding this comment.
Check that ensures cost components of elec heat sourc elec are non-zero is added
| ) | ||
| total_opex += variable_operational_cost | ||
|
|
||
| np.testing.assert_allclose( |
There was a problem hiding this comment.
The obj is not tested anymore. Please add it to the new function "cost_calculation_test" in the test utils. But this check of obj value is not always required. So create a new input for the function "cost_calculation_test", something like check_objective_function and make the default value False.
So for this specific test case the input variable will be set to check_objective_function=True. Then for all the other test case check_objective_function does not have to be set, if the objective function value is not tested
| ) | ||
|
|
||
|
|
||
| def _get_esdl_scaled_cost(cost_esdl_info, uni_enum): |
There was a problem hiding this comment.
please add docstring for this function
There was a problem hiding this comment.
docstring is added
| return cost_scaled | ||
|
|
||
|
|
||
| def cost_calculation_test(solution, results, atol=1e-8): |
There was a problem hiding this comment.
please add a docstring for this function
There was a problem hiding this comment.
docstring is added
| # Investment Cost | ||
| investment_cost = 0.0 | ||
| if asset not in solution.energy_system_components.get("gas_pipe", []): | ||
| investment_cost_info = _get_esdl_scaled_cost( |
There was a problem hiding this comment.
Can we add testing for the the cost coefficient itself, to check that the value in the esdl (which investment_cost_info) is the same as the value stored in the MESIDO parameters (whic his parameters[f"{asset}.variable_operational_cost_coefficient"] in this case)
The benefit is that we are also checking if we have parsed and save the actual cost coef correctly. Can you add this to all the other cost coefficients in this function please
There was a problem hiding this comment.
I added the suggested checks except "installation cost"and investemt cost of heat pipes. Because, there is no variable called installation_cost_coefficient. I could not figured out the reason but I see that parameters[f"{asset}.investment_cost_coefficient"] and investment_cost_info are different from each other.
| np.testing.assert_allclose( | ||
| variable_operational_cost, results[f"{asset}__variable_operational_cost"] | ||
| ) | ||
| total_opex += variable_operational_cost |
There was a problem hiding this comment.
please add a check for the obj function, but only checking it if check_objective_function=True
There was a problem hiding this comment.
For a check on the objective function, you need to check the state of the asset (whether it is enabled or optional)
|
|
||
| hp_id = name_to_id_map["HeatPump_b97e"] | ||
|
|
||
| cost_calculation_test(heat_problem, results) |
There was a problem hiding this comment.
The first tests should be related to the physics, heat_demand_matching energy_conservation and heat_to_discharge tests as these tests also tell us whether the majority of the code is working. If there already an issue occurs then the costs calucation might also fail, but that is then not the cause.
This is for all the tests
There was a problem hiding this comment.
I agree. order of the cost test is changed.
| for ii in range(1, len(solution.times())): | ||
| variable_operational_cost += ( | ||
| var_op_costs_esdl | ||
| * nominator_vector[ii] | ||
| * timesteps_hr[ii - 1] | ||
| / denominator | ||
| ) |
There was a problem hiding this comment.
No for loop for the times is need, like discussed before. also in the elif below.
There was a problem hiding this comment.
for loops are removed and generalized by vector multiplication at the bottom
| *transport_assets, | ||
| ] | ||
|
|
||
| pipe_classes = [ |
There was a problem hiding this comment.
rename to gas_pipe_classes
There was a problem hiding this comment.
renamed to gas_pipe_classes
| elif asset in solution.energy_system_components.get("heat_pipe", []): | ||
| investment_cost = investment_cost_info * parameters[f"{asset}.length"] | ||
| elif asset in solution.energy_system_components.get("electricity_cable", []): | ||
| investment_cost = investment_cost_info * parameters[f"{asset}.length"] |
There was a problem hiding this comment.
combine these elif statements
| ) | ||
|
|
||
| # Installation Cost | ||
| if asset not in transport_assets: |
There was a problem hiding this comment.
Why are transport_assets excluded? Wouldn't it be better to check that it is 0.0 or None and thus also 0.0
There was a problem hiding this comment.
Yes, that would be better. I will add check for also transport assets
| * timesteps_hr[ii - 1] | ||
| / denominator | ||
| ) | ||
| elif asset in solution.energy_system_components.get("airco", []): |
There was a problem hiding this comment.
Missing an else statement. Now there are several elif statemetns, but those do not cover all the non transport assets, so without realising you are missing out on several assets. I believe all those assets should be calculated and checked. Also the heat demand etc.
There was a problem hiding this comment.
I would also prefer an "else .... error exit" to cater for cases when new assets are added, which are not included in the test. This way we are made aware of an issue, else we might think the test is doing something where is might not be doing/testing anything
| for ii in range(1, len(solution.times())): | ||
| variable_operational_cost += ( | ||
| var_op_costs_esdl * nominator_vector[ii] * timesteps_hr[ii - 1] | ||
| ) |
There was a problem hiding this comment.
Can be moved down and generalized instead of being repeated several times, all variable opex is calculated with var_op_costs_esdl * nominator*dt/denominator.
There was a problem hiding this comment.
I agree. now it is moved down
| np.testing.assert_allclose( | ||
| variable_operational_cost, results[f"{asset}__variable_operational_cost"] | ||
| ) | ||
| total_opex += variable_operational_cost |
There was a problem hiding this comment.
For a check on the objective function, you need to check the state of the asset (whether it is enabled or optional)
There was a problem hiding this comment.
I think the costs check on demands that is covered in this test can also be removed once it is included in cost_calculation_test
There was a problem hiding this comment.
test_max_size_and_optional_assets.py also contains many costs checks, some hard-coded values, those you should keep, but the once where it checks the calculation you should remove and add the cost_calculation_test
|
@tolga-akan review completed |
tolga-akan
left a comment
There was a problem hiding this comment.
@KobusVanRooyen and @FJanssen-TNO I tried to address the comments as much as possible but it is not complete yet. There are still missing points that I could not respond due to lack of time.
Crete a new general function in utilts test to check all the cost components in the problem
TODO:
Modify var-opex part for: