Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/docs/_build/
/docs/_build/doctrees/
/docs/_build/html/
/.idea/
/.idea/
/inputs/
7 changes: 7 additions & 0 deletions src/B_read_from_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
ELECTRICITY_MG_FOLDER,
STORAGE_FOLDER,
LP_FILES_FOLDER,
USE_BIDIRECTIONAL_INVERTER_CONSTRAINT,
)

# requires xlrd
Expand Down Expand Up @@ -414,6 +415,12 @@ def get_case_definitions(file, sheet_project_sites):
f"Parameter {EVALUATION_PERSPECTIVE} has to be either {AC_SYSTEM} or {DC_SYSTEM}, but is {case_definitions[case][EVALUATION_PERSPECTIVE]}"
)

if USE_BIDIRECTIONAL_INVERTER_CONSTRAINT not in case_definitions[case]:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good. Maybe write a pytest for this function that makes sure that your two outcomes (USE_BIDIRECTIONAL_INVERTER_CONSTRAINT is not and is in settings) are checked.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes will look into pytest next

case_definitions[case][USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] = False
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Especially because of this, I think you need to use json.update(). With the pytest you will figure out if there are bugs in your code, even if the code initially passes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will the json.update() do?

logging.error(
f"Parameter {USE_BIDIRECTIONAL_INVERTER_CONSTRAINT} was not defined in excel input sheet and thus set to False."
)

case_definitions[case].update(
{
NUMBER_OF_EQUAL_GENERATORS: int(
Expand Down
2 changes: 2 additions & 0 deletions src/C_sensitivity_experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
INVERTER_DC_AC_COST_VAR,
INVERTER_DC_AC_EFFICIENCY,
INVERTER_DC_AC_LIFETIME,
INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR,
MAINGRID_DISTANCE,
MAINGRID_ELECTRICITY_PRICE,
MAINGRID_EXTENSION_COST_INVESTMENT,
Expand Down Expand Up @@ -1112,6 +1113,7 @@ def test_techno_economical_parameters_complete(experiment):
INVERTER_DC_AC_COST_VAR: 0,
INVERTER_DC_AC_EFFICIENCY: 1,
INVERTER_DC_AC_LIFETIME: 15,
INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR: 1,
MAINGRID_DISTANCE: 0,
MAINGRID_ELECTRICITY_PRICE: 0.15,
MAINGRID_EXTENSION_COST_INVESTMENT: 0,
Expand Down
8 changes: 8 additions & 0 deletions src/F_case_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
SHARE_USAGE,
SHARE_HYBRID,
DEFAULT,
USE_BIDIRECTIONAL_INVERTER_CONSTRAINT,
)

# This is not really a necessary class, as the whole experiement could be given to the function, but it ensures, that
Expand Down Expand Up @@ -278,6 +279,13 @@ def update_dict(capacities_oem, specific_case, experiment):
experiment_case_dict[ENABLE_INVERTER_ONLY_AT_BLACKOUT] = specific_case[
ENABLE_INVERTER_ONLY_AT_BLACKOUT
]

#################################################
# Include use bidirectional inverter constraint #
#################################################

experiment_case_dict[USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] = specific_case[USE_BIDIRECTIONAL_INVERTER_CONSTRAINT]

return experiment_case_dict


Expand Down
51 changes: 48 additions & 3 deletions src/G1_oemof_create_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
STORAGE_FIXED_CAPACITY,
STORAGE_FIXED_POWER,
RECTIFIER_AC_DC_FIXED_CAPACITY,
RECTIFIER_AC_DC_COST_INVESTMENT,
INVERTER_DC_AC_FIXED_CAPACITY,
INVERTER_DC_AC_COST_INVESTMENT,
INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR,
USE_BIDIRECTIONAL_INVERTER_CONSTRAINT,
ALLOW_SHORTAGE,
STABILITY_CONSTRAINT,
SHARE_BACKUP,
Expand Down Expand Up @@ -220,9 +224,9 @@ def build(experiment, case_dict):
# ------------point of coupling (feedin)------------#
if case_dict[PCC_FEEDIN_FIXED_CAPACITY] == None:
pass
# pointofcoupling_feedin = None
pointofcoupling_feedin = None
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional removal of #?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is an intentional removal because I need it later on in the code for the constraint_equate_bidirectional_transformer_capacities function (see line 462-471) in case PCC_FEEDIN_FIXED_CAPACITY is None.

elif case_dict[PCC_FEEDIN_FIXED_CAPACITY] is False:
generate.pointofcoupling_feedin_oem(
pointofcoupling_feedin = generate.pointofcoupling_feedin_oem(
micro_grid_system,
bus_electricity_ac,
bus_electricity_ng_feedin,
Expand All @@ -231,7 +235,7 @@ def build(experiment, case_dict):
)

elif isinstance(case_dict[PCC_FEEDIN_FIXED_CAPACITY], float):
generate.pointofcoupling_feedin_fix(
pointofcoupling_feedin = generate.pointofcoupling_feedin_fix(
micro_grid_system,
bus_electricity_ac,
bus_electricity_ng_feedin,
Expand Down Expand Up @@ -452,6 +456,45 @@ def build(experiment, case_dict):
+ " faulty at renewable_share_constraint. Value can only be True or False"
)

# ------------Link transformer station capacities constraint ------------#
if case_dict[PCC_CONSUMPTION_FIXED_CAPACITY] != None and case_dict[PCC_FEEDIN_FIXED_CAPACITY] != None:
logging.info("Added constraint: Linking transformer station capacities.")
constraints_custom.constraint_equate_bidirectional_transformer_capacities(
model,
case_dict,
bus_electricity_ng_feedin,
bus_electricity_ng_consumption,
pointofcoupling_feedin,
pointofcoupling_consumption,
PCC_FEEDIN_FIXED_CAPACITY,
PCC_CONSUMPTION_FIXED_CAPACITY
)

# ------------Link rectifier and inverter capacities constraint------------#
if case_dict[USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] != None:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can it be None? Isnt your default False?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be false indeed

if case_dict[USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] is True:
logging.info("Added constraint: Linking rectifier and inverter capacities.")
constraints_custom.constraint_equate_bidirectional_transformer_capacities(
model,
case_dict,
bus_electricity_dc,
bus_electricity_ac,
inverter,
rectifier,
INVERTER_DC_AC_FIXED_CAPACITY,
RECTIFIER_AC_DC_FIXED_CAPACITY,
experiment[INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR]
)
if experiment[RECTIFIER_AC_DC_COST_INVESTMENT] != 0:
logging.warning(
"Case definition of "
+ case_dict[CASE_NAME]
+ ": Are you sure that you want to define both rectifier and inverter costs if "
+ "you link the capacties to receive a biderectional inverter? "
+ "This would result in effective investment costs of "
+ str(float(experiment[RECTIFIER_AC_DC_COST_INVESTMENT])+float(case_dict[INVERTER_AC_DC_COST_INVESTMENT]))
+ " currency/kW bidirectional inverter."
)
# ------------Force charge from maingrid------------#
if case_dict[FORCE_CHARGE_FROM_MAINGRID] is False:
pass
Expand Down Expand Up @@ -497,6 +540,7 @@ def build(experiment, case_dict):
+ " faulty at enable_inverter_at_backout. Value can only be True or False"
)


"""
# ------------Allow shortage only for certain percentage of demand in a timestep------------#
if case_dict['allow_shortage'] is True:
Expand All @@ -507,6 +551,7 @@ def build(experiment, case_dict):
shortage_constraints.timestep(model, case_dict, experiment, sink_demand_dc,
source_shortage, bus_electricity_dc)
"""

return micro_grid_system, model


Expand Down
13 changes: 13 additions & 0 deletions src/G2b_constraints_custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pyomo.environ as po
import logging
import pandas as pd
import oemof.solph as solph
from src.constants import (
SHORTAGE_LIMIT,
NUMBER_OF_EQUAL_GENERATORS,
Expand Down Expand Up @@ -954,6 +955,18 @@ def inverter_only_at_blackout_test(case_dict, oemof_results, e_flows_df):

return

# equate bi-directional transformer capacities
def constraint_equate_bidirectional_transformer_capacities(model, case_dict, bus_transformer_in, bus_transformer_out, transformer_in, transformer_out, name_transformer_in, name_transformer_out, factor = 1):
CAP_inverter = 0
CAP_rectifier = 0
if case_dict[name_transformer_in] != None and case_dict[name_transformer_out] != None:
if case_dict[name_transformer_in] is False and case_dict[name_transformer_out] is False:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this loop do? Dont forget to use in-line comments (#), and also add docstrings to your functions (typing `r"""`` will probably aid you in writing them)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright will add comments for the next PR

Copy link
Copy Markdown
Collaborator Author

@remmyd remmyd Sep 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually I took the idea from one of your comments (#155 (comment)) but I'm not sure in what case case_dict[name_transformer_in] is false and why different capacities need to be added (see code below) since there's just one converter
CAP_inverter += model.InvestmentFlow.invest[bus_transformer_in, transformer_in]
CAP_rectifier += model.InvestmentFlow.invest[bus_transformer_out, transformer_out]
Could you clarify what it represents?

CAP_inverter += model.InvestmentFlow.invest[bus_transformer_in, transformer_in]
CAP_rectifier += model.InvestmentFlow.invest[bus_transformer_out, transformer_out]
solph.constraints.equate_variables(model,CAP_rectifier, CAP_inverter, factor)

return model


# todo shortage constraint / stbaility constraint only relates to AC bus
def timestep(model, case_dict, experiment, el_bus, sink_demand, source_shortage):
Expand Down
2 changes: 2 additions & 0 deletions src/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
INVERTER_DC_AC_COST_VAR = "inverter_dc_ac_cost_var"
INVERTER_DC_AC_EFFICIENCY = "inverter_dc_ac_efficiency"
INVERTER_DC_AC_LIFETIME = "inverter_dc_ac_lifetime"
INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR = "inverter_rectifier_capactiy_ratio_factor"
MAINGRID_DISTANCE = "maingrid_distance"
MAINGRID_ELECTRICITY_PRICE = "maingrid_electricity_price"
MAINGRID_EXTENSION_COST_INVESTMENT = "maingrid_extension_cost_investment"
Expand Down Expand Up @@ -308,6 +309,7 @@
WIND_FIXED_CAPACITY = "wind_fixed_capacity"
RECTIFIER_AC_DC_FIXED_CAPACITY = "rectifier_ac_dc_fixed_capacity"
INVERTER_DC_AC_FIXED_CAPACITY = "inverter_dc_ac_fixed_capacity"
USE_BIDIRECTIONAL_INVERTER_CONSTRAINT = "use_bidirectional_inverter_constraint"
ALLOW_SHORTAGE = "allow_shortage"
STABILITY_CONSTRAINT = "stability_constraint"
RENEWABLE_CONSTRAINT = "renewable_constraint"
Expand Down