Skip to content

Commit

Permalink
improve OPF documentation and _check_necessary_opf_parameters()
Browse files Browse the repository at this point in the history
  • Loading branch information
SteffenMeinecke committed Sep 26, 2019
1 parent f09b540 commit 870e0f0
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Change Log
=============
- [CHANGED] OPF documentation and _check_necessary_opf_parameters()
- [FIXDED] dtype at element parameter in cost tables
- [ADDED] reindex_buses() toolbox function
- [ADDED] toolbox function select_subnet now also copies cost data and net parameters
Expand Down
2 changes: 2 additions & 0 deletions doc/opf/opf_flexibility.csv
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@
:math:`Q_{min,eg} \leq Q_{eg} \leq Q_{max,eg},\ eg \ \epsilon \ ext\_grid` ;net.ext_grid.min_q_mvar / net.ext_grid.max_q_mvar
:math:`P_{min,ld} \leq P_{ld} \leq P_{max,ld},\ ld \ \epsilon \ load` ;net.load.min_p_mw / net.load.max_p_mw
:math:`Q_{min,ld} \leq Q_{ld} \leq Q_{max,ld},\ ld \ \epsilon \ load` ;net.load.min_q_mvar / net.load.max_q_mvar
:math:`P_{min,st} \leq P_{st} \leq P_{max,st},\ st \ \epsilon \ storage` ;net.storage.min_p_mw / net.storage.max_p_mw
:math:`Q_{min,st} \leq Q_{st} \leq Q_{max,st},\ st \ \epsilon \ storage` ;net.storage.min_q_mvar / net.storage.max_q_mvar
56 changes: 27 additions & 29 deletions pandapower/opf/validate_opf_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,37 @@ def _check_necessary_opf_parameters(net, logger):
error = False
for element_type, columns in opf_col.items():
if len(net[element_type]):
missing_col = columns.loc[~columns.isin(net[element_type].columns)].values
# --- ensure "controllable" as column
controllable = True
if element_type in ['gen', 'sgen', 'load', 'storage']:
if 'controllable' in net[element_type]:

# --- determine controllables
if element_type in ["ext_grid", "dcline"]:
controllables = net[element_type].index
else:
if "controllable" in net[element_type].columns:
if element_type == 'gen':
net[element_type].controllable.fillna(True, inplace=True)
else: # 'sgen', 'load'
else: # 'sgen', 'load', 'storage'
net[element_type].controllable.fillna(False, inplace=True)
if not net[element_type].controllable.any():
controllable = False
controllables = net[element_type].index[net[element_type].controllable]
else:
controllable = False
controllables = net[element_type].index if element_type == 'gen' else []

missing_col = columns.loc[~columns.isin(net[element_type].columns)].values
na_col = [col for col in set(columns)-set(missing_col) if
net[element_type][col].isnull().any()]

# --- logging for missing data in element tables with controllables
if controllable:
if len(missing_col):
if element_type != "ext_grid":
logger.error("These columns are missing in " + element_type + ": " +
str(missing_col))
error = True
else: # "ext_grid" -> no error due to missing columns at ext_grid
logger.debug("These missing columns in ext_grid are considered in OPF as " +
"+- 1000 TW.: " + str(missing_col))
# determine missing values
for lim_col in set(columns) - set(missing_col):
if element_type in ['gen', 'sgen', 'load', 'storage']:
controllables = net[element_type].loc[net[element_type].controllable].index
else: # 'ext_grid', 'dcline'
controllables = net[element_type].index
if net[element_type][lim_col].loc[controllables].isnull().any():
missing_val.append(element_type)
break
if len(controllables) and len(missing_col):
if element_type != "ext_grid":
logger.error("These columns are missing in " + element_type + ": " +
str(missing_col))
error = True
else: # "ext_grid" -> no error due to missing columns at ext_grid
logger.debug("These missing columns in ext_grid are considered in OPF as " +
"+- 1000 TW.: " + str(missing_col))
# determine missing values
if len(na_col):
missing_val.append(element_type)

if missing_val:
logger.info("These elements have missing power constraint values, which are considered " +
"in OPF as +- 1000 TW: " + str(missing_val))
Expand All @@ -58,14 +56,14 @@ def _check_necessary_opf_parameters(net, logger):
logger.info("There are missing bus.min_vm_pu values, which are considered in OPF as " +
"0.0 pu.")
else:
logger.info("min_vm_pu is missing in bus table. In OPF these limits are considered as " +
logger.info("'min_vm_pu' is missing in bus table. In OPF these limits are considered as " +
"0.0 pu.")
if 'max_vm_pu' in net.bus.columns:
if net.bus.max_vm_pu.isnull().any():
logger.info("There are missing bus.max_vm_pu values, which are considered in OPF as " +
"2.0 pu.")
else:
logger.info("max_vm_pu is missing in bus table. In OPF these limits are considered as " +
logger.info("'max_vm_pu' is missing in bus table. In OPF these limits are considered as " +
"2.0 pu.")

if error:
Expand Down
15 changes: 9 additions & 6 deletions pandapower/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,19 +268,22 @@ def runopp(net, verbose=False, calculate_voltage_angles=False, check_connectivit
Runs the pandapower Optimal Power Flow.
Flexibilities, constraints and cost parameters are defined in the pandapower element tables.
Flexibilities can be defined in net.sgen / net.gen /net.load
Flexibilities can be defined in net.sgen / net.gen /net.load / net.storage
net.sgen.controllable if a static generator is controllable. If False,
the active and reactive power are assigned as in a normal power flow. If True, the following
flexibilities apply:
- net.sgen.min_p_mw / net.sgen.max_p_mw
- net.sgen.min_q_mvar / net.sgen.max_q_mvar
- net.load.min_p_mw / net.load.max_p_mw
- net.load.min_q_mvar / net.load.max_q_mvar
- net.gen.min_p_mw / net.gen.max_p_mw
- net.gen.min_q_mvar / net.gen.max_q_mvar
- net.sgen.min_p_mw / net.sgen.max_p_mw
- net.sgen.min_q_mvar / net.sgen.max_q_mvar
- net.dcline.max_p_mw
- net.dcline.min_q_to_mvar / net.dcline.max_q_to_mvar / net.dcline.min_q_from_mvar / net.dcline.max_q_from_mvar
- net.ext_grid.min_p_mw / net.ext_grid.max_p_mw
- net.ext_grid.min_q_mvar / net.ext_grid.max_q_mvar
- net.dcline.min_q_to_mvar / net.dcline.max_q_to_mvar / net.dcline.min_q_from_mvar / net.dcline.max_q_from_mvar
- net.load.min_p_mw / net.load.max_p_mw
- net.load.min_q_mvar / net.load.max_q_mvar
- net.storage.min_p_mw / net.storage.max_p_mw
- net.storage.min_q_mvar / net.storage.max_q_mvar
Controllable loads behave just like controllable static generators. It must be stated if they are controllable.
Otherwise, they are not respected as flexibilities.
Expand Down

0 comments on commit 870e0f0

Please sign in to comment.