Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
topupopt
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pmag
topupopt
Merge requests
!6
Stats
Code
Review changes
Check out branch
Open in Workspace
Download
Patches
Plain diff
Expand sidebar
Merged
Stats
stats
into
master
Overview
0
Commits
14
Pipelines
0
Changes
25
Merged
Stats
pmag
requested to merge
stats
into
master
May 30, 2024
Overview
0
Commits
14
Pipelines
0
Changes
12
Problem statistics
Profile generation
Graph simplification
Tests for the above
0
0
Merge request reports
Compare
version 1
version 1
e5eaedf8
May 30, 2024
master (base)
and
latest version
latest version
4fa48ce4
14 commits,
Jun 2, 2024
version 1
e5eaedf8
10 commits,
May 30, 2024
Show latest version
12 files
+
3748
−
1400
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Some changes are not shown
For a faster browsing experience, some files are collapsed by default.
Expand all files
Files
12
src/topupopt/problems/esipp/blocks/converters.py
0 → 100644
+
1007
−
0
View file @ 4fa48ce4
Edit in single-file editor
Open in Web IDE
# imports
import
pyomo.environ
as
pyo
# *****************************************************************************
# *****************************************************************************
def
add_converters
(
model
:
pyo
.
AbstractModel
,
enable_default_values
:
bool
=
True
,
enable_validation
:
bool
=
True
,
enable_initialisation
:
bool
=
True
,
):
# *************************************************************************
# *************************************************************************
# systems
# set of all systems
model
.
set_I
=
pyo
.
Set
()
# set of optional systems
model
.
set_I_new
=
pyo
.
Set
(
within
=
model
.
set_I
)
# *************************************************************************
# inputs
# set of inputs (indexed by system)
model
.
set_M
=
pyo
.
Set
(
model
.
set_I
)
# set of inputs modelled using non-negative real variables
model
.
set_M_nnr
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_M
)
# set of inputs modelled using binary variables
model
.
set_M_bin
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_M
)
# set of amplitude-constrained inputs
model
.
set_M_dim
=
pyo
.
Set
(
model
.
set_I_new
,
within
=
model
.
set_M
)
# set of amplitude-constrained inputs
model
.
set_M_fix
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_M
)
# set of externality-inducing inputs
model
.
set_M_ext
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_M
)
# *************************************************************************
# outputs
# set of outputs (indexed by system)
model
.
set_R
=
pyo
.
Set
(
model
.
set_I
)
# set of outputs with fixed bounds
model
.
set_R_fix
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_R
)
# set of positive amplitude-constrained outputs
model
.
set_R_dim_pos
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_R
)
# set of negative amplitude-constrained outputs
model
.
set_R_dim_neg
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_R
)
# set of amplitude-limited outputs with matching pos. and neg. amplitudes
model
.
set_R_dim_eq
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_R
)
# set of outputs (indexed by system) inducing externalities
model
.
set_R_ext
=
pyo
.
Set
(
model
.
set_I
)
# *************************************************************************
# states
# set of states
model
.
set_N
=
pyo
.
Set
(
model
.
set_I
)
# set of states with fixed bounds
model
.
set_N_fix
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# set of positive amplitude-constrained states
model
.
set_N_dim_pos
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# set of negative amplitude-constrained states
model
.
set_N_dim_neg
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# set of amplitude-limited states with matching pos. and neg. amplitudes
model
.
set_N_dim_eq
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# set of states (indexed by system) inducing externalities
model
.
set_N_ext
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# set of positive state variation-penalised states
model
.
set_N_pos_var
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# set of negative state variation-penalised states
model
.
set_N_neg_var
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# set of upper reference violation-penalised states
model
.
set_N_ref_u
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# set of lower reference violation-penalised states
model
.
set_N_ref_d
=
pyo
.
Set
(
model
.
set_I
,
within
=
model
.
set_N
)
# *************************************************************************
# *************************************************************************
# sparse index sets
# *************************************************************************
# *************************************************************************
# inputs
# set of IM tuples
def
init_set_IM
(
m
):
return
((
i
,
m_i
)
for
i
in
m
.
set_I
for
m_i
in
m
.
set_M
[
i
])
model
.
set_IM
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IM
)
# set of IM tuples for systems with binary signals
def
init_set_IM_bin
(
m
):
return
((
i
,
m_i
)
for
(
i
,
m_i
)
in
m
.
set_IM
if
m_i
in
m
.
set_M_bin
[
i
])
model
.
set_IM_bin
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IM_bin
,
within
=
model
.
set_IM
)
# set of IM tuples for tech. with dimensionable reference mode levels
def
init_set_IM_dim
(
m
):
return
((
i
,
m_i
)
for
(
i
,
m_i
)
in
m
.
set_IM
if
m_i
in
m
.
set_M_dim
[
i
])
model
.
set_IM_dim
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IM_dim
,
within
=
model
.
set_IM
)
# set of IM tuples for fixed amplitude inputs
def
init_set_IM_fix
(
m
):
return
((
i
,
m_i
)
for
(
i
,
m_i
)
in
m
.
set_IM
if
m_i
in
m
.
set_M_fix
[
i
])
model
.
set_IM_fix
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IM_fix
,
within
=
model
.
set_IM
)
# set of IM tuples for technologies whose modes can induce externalities
def
init_set_IM_ext
(
m
):
return
((
i
,
m_i
)
for
(
i
,
m_i
)
in
m
.
set_IM
if
m_i
in
m
.
set_M_ext
[
i
])
model
.
set_IM_ext
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IM_ext
,
within
=
model
.
set_IM
)
# *************************************************************************
# states
# set of IN tuples
def
init_set_IN
(
m
):
return
(
(
i
,
n_i
)
for
i
in
m
.
set_I
for
n_i
in
m
.
set_N
[
i
]
# IN tuple
)
# for each state
model
.
set_IN
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN
)
# set of IN tuples for states with fixed bounds
def
init_set_IN_fix
(
m
):
return
((
i
,
n_i
)
for
i
in
m
.
set_I
for
n_i
in
m
.
set_N_fix
[
i
])
model
.
set_IN_fix
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_fix
)
# set of IN tuples for converters with amplitude-constrained states
def
init_set_IN_dim_eq
(
m
):
return
((
i
,
n_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
if
n_i
in
m
.
set_N_dim_eq
[
i
])
model
.
set_IN_dim_eq
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_dim_eq
,
within
=
model
.
set_IN
)
# set of IN tuples for converters with pos. amplitude-constrained states
def
init_set_IN_dim_pos
(
m
):
return
((
i
,
n_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
if
n_i
in
m
.
set_N_dim_pos
[
i
])
model
.
set_IN_dim_pos
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_dim_pos
,
within
=
model
.
set_IN
)
# set of IN tuples for converters with neg. amplitude-constrained states
def
init_set_IN_dim_neg
(
m
):
return
((
i
,
n_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
if
n_i
in
m
.
set_N_dim_neg
[
i
])
model
.
set_IN_dim_neg
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_dim_neg
,
within
=
model
.
set_IN
)
# set of IN tuples for converters with externality-inducing states
def
init_set_IN_ext
(
m
):
return
((
i
,
n_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
if
n_i
in
m
.
set_N_ext
[
i
])
model
.
set_IN_ext
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_ext
,
within
=
model
.
set_IN
)
# set of IN tuples for positive variation-penalised states
def
init_set_IN_pos_var
(
m
):
return
((
i
,
n_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
if
n_i
in
m
.
set_N_pos_var
[
i
])
model
.
set_IN_pos_var
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_pos_var
,
within
=
model
.
set_IN
)
# set of IN tuples for negative variation-penalised states
def
init_set_IN_neg_var
(
m
):
return
((
i
,
n_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
if
n_i
in
m
.
set_N_neg_var
[
i
])
model
.
set_IN_neg_var
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_neg_var
,
within
=
model
.
set_IN
)
# set of IN tuples for upper reference violation penalised states
def
init_set_IN_ref_u
(
m
):
return
((
i
,
n_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
if
n_i
in
m
.
set_N_ref_u
[
i
])
model
.
set_IN_ref_u
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_ref_u
,
within
=
model
.
set_IN
)
# set of IN tuples for lower reference violation penalised states
def
init_set_IN_ref_d
(
m
):
return
((
i
,
n_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
if
n_i
in
m
.
set_N_ref_d
[
i
])
model
.
set_IN_ref_d
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IN_ref_d
,
within
=
model
.
set_IN
)
# *************************************************************************
# outputs
# set of IR tuples
def
init_set_IR
(
m
):
return
((
i
,
r_i
)
for
i
in
m
.
set_I
for
r_i
in
m
.
set_R
[
i
])
model
.
set_IR
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IR
)
# set of IR tuples for outputs with fixed bounds
def
init_set_IR_fix
(
m
):
return
((
i
,
r_i
)
for
i
in
m
.
set_I
for
r_i
in
m
.
set_R_fix
[
i
])
model
.
set_IR_fix
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IR_fix
)
# set of IR tuples for converters with matching pos. and neg. out. amp. limits
def
init_set_IR_dim_eq
(
m
):
return
((
i
,
r_i
)
for
(
i
,
r_i
)
in
m
.
set_IR
if
r_i
in
m
.
set_R_dim_eq
[
i
])
model
.
set_IR_dim_eq
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IR_dim_eq
)
# set of IR tuples for converters with amplitude-penalised outputs
def
init_set_IR_dim_neg
(
m
):
return
((
i
,
r_i
)
for
(
i
,
r_i
)
in
m
.
set_IR
if
r_i
in
m
.
set_R_dim_neg
[
i
])
model
.
set_IR_dim_neg
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IR_dim_neg
)
# set of IR tuples for converters with amplitude-penalised outputs
def
init_set_IR_dim
(
m
):
return
((
i
,
r_i
)
for
(
i
,
r_i
)
in
m
.
set_IR
if
r_i
in
m
.
set_R_dim
[
i
])
model
.
set_IR_dim
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IR_dim
)
# set of IR tuples for converters with pos. amplitude-constrained outputs
def
init_set_IR_dim_pos
(
m
):
return
((
i
,
r_i
)
for
(
i
,
r_i
)
in
m
.
set_IR
if
r_i
in
m
.
set_R_dim_pos
[
i
])
model
.
set_IR_dim_pos
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IR_dim_pos
)
# set of IR tuples for converters with externality-inducing outputs
def
init_set_IR_ext
(
m
):
return
((
i
,
r_i
)
for
(
i
,
r_i
)
in
m
.
set_IR
if
r_i
in
m
.
set_R_ext
[
i
])
model
.
set_IR_ext
=
pyo
.
Set
(
dimen
=
2
,
initialize
=
init_set_IR_ext
)
# *************************************************************************
# combined inputs/states/outputs
# TODO: narrow down these sets if possible
# set of INN tuples
def
init_set_INN
(
m
):
return
((
i
,
n1
,
n2
)
for
(
i
,
n1
)
in
m
.
set_IN
for
n2
in
m
.
set_N
[
i
])
model
.
set_INN
=
pyo
.
Set
(
dimen
=
3
,
initialize
=
init_set_INN
)
# set of INM tuples
def
init_set_INM
(
m
):
return
((
i
,
n_i
,
m_i
)
for
(
i
,
n_i
)
in
m
.
set_IN
for
m_i
in
m
.
set_M
[
i
])
model
.
set_INM
=
pyo
.
Set
(
dimen
=
3
,
initialize
=
init_set_INM
)
# set of IRM tuples
def
init_set_IRM
(
m
):
return
(
(
i
,
r_i
,
m_i
)
for
(
i
,
r_i
)
in
m
.
set_IR
for
m_i
in
m
.
set_M
[
i
]
)
# can be further constrained
model
.
set_IRM
=
pyo
.
Set
(
dimen
=
3
,
initialize
=
init_set_IRM
)
# set of IRN tuples
def
init_set_IRN
(
m
):
return
(
(
i
,
r_i
,
n_i
)
for
(
i
,
r_i
)
in
m
.
set_IR
for
n_i
in
m
.
set_N
[
i
]
)
# can be further constrained
model
.
set_IRN
=
pyo
.
Set
(
dimen
=
3
,
initialize
=
init_set_IRN
)
# *************************************************************************
# *************************************************************************
# parameters
# converters
# externality cost per input unit
model
.
param_c_ext_u_imqk
=
pyo
.
Param
(
model
.
set_IM_ext
,
model
.
set_QK
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# externality cost per output unit
model
.
param_c_ext_y_irqk
=
pyo
.
Param
(
model
.
set_IR_ext
,
model
.
set_QK
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# externality cost per state unit
model
.
param_c_ext_x_inqk
=
pyo
.
Param
(
model
.
set_IN_ext
,
model
.
set_QK
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit cost of positive state variations
model
.
param_c_pos_var_in
=
pyo
.
Param
(
model
.
set_IN_pos_var
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit cost of negative state variations
model
.
param_c_neg_var_in
=
pyo
.
Param
(
model
.
set_IN_neg_var
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit cost of upper state reference violations
model
.
param_c_ref_u_inqk
=
pyo
.
Param
(
model
.
set_IN_ref_u
,
model
.
set_QK
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit cost of lower state reference violations
model
.
param_c_ref_d_inqk
=
pyo
.
Param
(
model
.
set_IN_ref_d
,
model
.
set_QK
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# minimum converter cost
model
.
param_c_cvt_min_i
=
pyo
.
Param
(
model
.
set_I_new
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit (positive) input amplitude cost
model
.
param_c_cvt_u_im
=
pyo
.
Param
(
model
.
set_IM_dim
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit output amplitude cost
model
.
param_c_cvt_y_ir
=
pyo
.
Param
(
model
.
set_IR_dim
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit positive state amplitude cost
model
.
param_c_cvt_x_pos_in
=
pyo
.
Param
(
model
.
set_IN_dim_pos
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit negative state amplitude cost
model
.
param_c_cvt_x_neg_in
=
pyo
.
Param
(
model
.
set_IN_dim_neg
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit positive output amplitude cost
model
.
param_c_cvt_y_pos_ir
=
pyo
.
Param
(
model
.
set_IR_dim_pos
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# unit negative output amplitude cost
model
.
param_c_cvt_y_neg_ir
=
pyo
.
Param
(
model
.
set_IR_dim_neg
,
within
=
pyo
.
NonNegativeReals
,
default
=
0
)
# *************************************************************************
# effect of system inputs on specific network and node pairs
model
.
param_a_nw_glimqk
=
pyo
.
Param
(
model
.
set_GL_not_exp_imp
,
model
.
set_IM
,
model
.
set_QK
,
default
=
0
,
# default: no effect
within
=
pyo
.
Reals
,
)
# effect of system outputs on specific network and node pairs
model
.
param_a_nw_glirqk
=
pyo
.
Param
(
model
.
set_GL_not_exp_imp
,
model
.
set_IR
,
model
.
set_QK
,
default
=
0
,
# default: no effect
within
=
pyo
.
Reals
,
)
# *************************************************************************
# inputs
# upper bounds for (non-binary, non-dimensionable) inputs
model
.
param_u_ub_imqk
=
pyo
.
Param
(
model
.
set_IM_fix
,
model
.
set_QK
,
within
=
pyo
.
PositiveReals
)
# maximum input limits
model
.
param_u_amp_max_im
=
pyo
.
Param
(
model
.
set_IM_dim
,
within
=
pyo
.
PositiveReals
,
default
=
1
)
# time interval-dependent adjustment coefficients for input limits
model
.
param_f_amp_u_imqk
=
pyo
.
Param
(
model
.
set_IM_dim
,
model
.
set_QK
,
within
=
pyo
.
PositiveReals
,
default
=
1
)
# *************************************************************************
# states
# initial conditions
model
.
param_x_inq0
=
pyo
.
Param
(
model
.
set_IN
,
model
.
set_Q
,
within
=
pyo
.
Reals
)
# fixed upper bounds for state variables
model
.
param_x_ub_irqk
=
pyo
.
Param
(
model
.
set_IN_fix
,
model
.
set_QK
,
within
=
pyo
.
Reals
)
# fixed lower bounds for state variables
model
.
param_x_lb_irqk
=
pyo
.
Param
(
model
.
set_IN_fix
,
model
.
set_QK
,
within
=
pyo
.
Reals
)
# maximum positive amplitude for states
model
.
param_x_amp_pos_max_in
=
pyo
.
Param
(
model
.
set_IN_dim_pos
,
within
=
pyo
.
PositiveReals
)
# maximum negative amplitude for states
model
.
param_x_amp_neg_max_in
=
pyo
.
Param
(
model
.
set_IN_dim_neg
,
within
=
pyo
.
PositiveReals
)
# adjustment of positive state amplitude limits
model
.
param_f_amp_pos_x_inqk
=
pyo
.
Param
(
model
.
set_IN_dim_pos
,
model
.
set_QK
,
within
=
pyo
.
PositiveReals
,
default
=
1
)
# adjustment of negative state amplitude limits
model
.
param_f_amp_neg_x_inqk
=
pyo
.
Param
(
model
.
set_IN_dim_neg
,
model
.
set_QK
,
within
=
pyo
.
PositiveReals
,
default
=
1
)
# state equations: coefficients from C matrix
model
.
param_a_eq_x_innqk
=
pyo
.
Param
(
model
.
set_INN
,
model
.
set_QK
,
default
=
0
,
within
=
pyo
.
Reals
# default: no effect
)
# state equations: coefficients from D matrix
model
.
param_b_eq_x_inmqk
=
pyo
.
Param
(
model
.
set_INM
,
model
.
set_QK
,
default
=
0
,
within
=
pyo
.
Reals
# default: no effect
)
# state equations: constant term
model
.
param_e_eq_x_inqk
=
pyo
.
Param
(
model
.
set_IN
,
model
.
set_QK
,
default
=
0
,
within
=
pyo
.
Reals
# default: no effect
)
# *************************************************************************
# outputs
# fixed upper bounds for output variables
model
.
param_y_ub_irqk
=
pyo
.
Param
(
model
.
set_IR_fix
,
model
.
set_QK
,
within
=
pyo
.
Reals
)
# fixed lower bounds for output variables
model
.
param_y_lb_irqk
=
pyo
.
Param
(
model
.
set_IR_fix
,
model
.
set_QK
,
within
=
pyo
.
Reals
)
# adjustment of positive output amplitude limits
model
.
param_f_amp_y_pos_irqk
=
pyo
.
Param
(
model
.
set_IR_dim_pos
,
model
.
set_QK
,
within
=
pyo
.
PositiveReals
,
default
=
1
)
# adjustment of negative output amplitude limits
model
.
param_f_amp_y_neg_irqk
=
pyo
.
Param
(
model
.
set_IR_dim_neg
,
model
.
set_QK
,
within
=
pyo
.
PositiveReals
,
default
=
1
)
# maximum positive amplitude limit for outputs
model
.
param_y_amp_pos_max_ir
=
pyo
.
Param
(
model
.
set_IR_dim_pos
,
within
=
pyo
.
PositiveReals
)
# maximum negative amplitude limit for outputs
model
.
param_y_amp_neg_max_ir
=
pyo
.
Param
(
model
.
set_IR_dim_neg
,
within
=
pyo
.
PositiveReals
)
# output equation coefficients from C matrix
model
.
param_c_eq_y_irnqk
=
pyo
.
Param
(
model
.
set_IRN
,
model
.
set_QK
,
default
=
0
,
within
=
pyo
.
Reals
# default: no effect
)
# output equation coefficients from D matrix
model
.
param_d_eq_y_irmqk
=
pyo
.
Param
(
model
.
set_IRM
,
model
.
set_QK
,
default
=
0
,
within
=
pyo
.
Reals
# default: no effect
)
# output equation constant
model
.
param_e_eq_y_irqk
=
pyo
.
Param
(
model
.
set_IR
,
model
.
set_QK
,
default
=
0
,
within
=
pyo
.
Reals
# default: no effect
)
# *************************************************************************
# *************************************************************************
# *************************************************************************
# *************************************************************************
# variables
# *************************************************************************
# *************************************************************************
# capex for installing individual converters
model
.
var_capex_cvt_i
=
pyo
.
Var
(
model
.
set_I_new
,
within
=
pyo
.
NonNegativeReals
)
# *************************************************************************
# converters
# decision to install converter i
model
.
var_cvt_inv_i
=
pyo
.
Var
(
model
.
set_I_new
,
within
=
pyo
.
Binary
)
# inputs
# input variables
def
bounds_var_u_imqk
(
m
,
i
,
m_i
,
q
,
k
):
if
(
i
,
m_i
)
in
m
.
param_u_ub_imqk
:
# predefined limit
return
(
0
,
m
.
param_u_ub_imqk
[(
i
,
m_i
,
q
,
k
)])
else
:
# dynamic limit (set elsewhere)
return
(
0
,
None
)
def
domain_var_u_imqk
(
m
,
i
,
m_i
,
q
,
k
):
try
:
if
m_i
in
m
.
set_M_bin
[
i
]:
return
pyo
.
Binary
# binary: {0,1}
else
:
return
pyo
.
NonNegativeReals
# nonnegative real: [0,inf]
except
KeyError
:
return
pyo
.
NonNegativeReals
# nonnegative real: [0,inf]
model
.
var_u_imqk
=
pyo
.
Var
(
model
.
set_IM
,
model
.
set_QK
,
domain
=
domain_var_u_imqk
,
# within=pyo.NonNegativeReals,
bounds
=
bounds_var_u_imqk
,
)
# input amplitude variables (only one per sign is needed, as vars. are nnr)
model
.
var_u_amp_im
=
pyo
.
Var
(
model
.
set_IM_dim
,
within
=
pyo
.
NonNegativeReals
)
# *************************************************************************
# outputs
# output variables
def
bounds_var_y_irqk
(
m
,
i
,
r
,
q
,
k
):
if
r
in
m
.
set_R_fix
:
# predefined limit
return
(
m
.
param_u_lb_irqk
[(
i
,
r
,
q
,
k
)],
m
.
param_u_ub_irqk
[(
i
,
r
,
q
,
k
)])
else
:
# do not enforce any limits
return
(
None
,
None
)
# def domain_var_y_irqk(m, i, r, k):
# try:
# if m_i in m.set_M_bin[i]:
# return pyo.Binary # binary: {0,1}
# else:
# return pyo.NonNegativeReals # nonnegative real: [0,inf]
# except KeyError:
# return pyo.NonNegativeReals # nonnegative real: [0,inf]
model
.
var_y_irqk
=
pyo
.
Var
(
model
.
set_IR
,
model
.
set_QK
,
bounds
=
bounds_var_y_irqk
,
within
=
pyo
.
Reals
)
# positive output amplitudes
model
.
var_y_amp_pos_ir
=
pyo
.
Var
(
model
.
set_IR_dim_pos
,
within
=
pyo
.
Reals
)
# output amplitudes
model
.
var_y_amp_neg_ir
=
pyo
.
Var
(
model
.
set_IR_dim_neg
,
within
=
pyo
.
Reals
)
# *************************************************************************
# states
# state variables
model
.
var_x_inqk
=
pyo
.
Var
(
model
.
set_IN
,
model
.
set_QK
,
within
=
pyo
.
Reals
)
# positive amplitude variables
model
.
var_x_amp_pos_in
=
pyo
.
Var
(
model
.
set_IN_dim_pos
,
within
=
pyo
.
NonNegativeReals
)
# negative amplitude variables
model
.
var_x_amp_neg_in
=
pyo
.
Var
(
model
.
set_IN_dim_neg
,
within
=
pyo
.
NonNegativeReals
)
# positive state variation
model
.
var_delta_x_pos_var_in
=
pyo
.
Var
(
model
.
set_IN_pos_var
,
within
=
pyo
.
NonNegativeReals
)
# negative state variation
model
.
var_delta_x_neg_var_in
=
pyo
.
Var
(
model
.
set_IN_neg_var
,
within
=
pyo
.
NonNegativeReals
)
# positive reference state violation
model
.
var_delta_x_ref_u_inqk
=
pyo
.
Var
(
model
.
set_IN_ref_u
,
model
.
set_QK
,
within
=
pyo
.
NonNegativeReals
)
# negative reference state violation
model
.
var_delta_x_ref_d_inqk
=
pyo
.
Var
(
model
.
set_IN_ref_d
,
model
.
set_QK
,
within
=
pyo
.
NonNegativeReals
)
# *************************************************************************
# *************************************************************************
# objective function
# capex for converters
def
rule_capex_converter
(
m
,
i
):
return
(
m
.
var_cvt_inv_i
[
i
]
*
m
.
param_c_cvt_min_i
[
i
]
+
sum
(
m
.
var_u_amp_im
[(
i
,
m_i
)]
*
m
.
param_c_cvt_u_im
[(
i
,
m_i
)]
for
m_i
in
m
.
set_M_dim_i
[
i
]
)
+
sum
(
m
.
var_x_amp_pos_in
[(
i
,
n
)]
*
m
.
param_c_cvt_x_pos_in
[(
i
,
n
)]
for
n
in
m
.
set_N_dim_pos
[
i
]
)
+
sum
(
m
.
var_x_amp_neg_in
[(
i
,
n
)]
*
m
.
param_c_cvt_x_neg_in
[(
i
,
n
)]
for
n
in
m
.
set_N_dim_neg
[
i
]
)
+
sum
(
m
.
var_y_amp_pos_ir
[(
i
,
r
)]
*
m
.
param_c_cvt_y_pos_ir
[(
i
,
r
)]
for
r
in
m
.
set_N_dim_pos
[
i
]
)
+
sum
(
m
.
var_y_amp_neg_ir
[(
i
,
r
)]
*
m
.
param_c_cvt_y_neg_ir
[(
i
,
r
)]
for
r
in
m
.
set_N_dim_neg
[
i
]
)
<=
m
.
var_capex_cvt_i
[
i
]
)
model
.
constr_capex_system
=
pyo
.
Constraint
(
model
.
set_I_new
,
rule
=
rule_capex_converter
)
# *************************************************************************
# *************************************************************************
# converters
# *************************************************************************
# *************************************************************************
# input signal limits for dimensionable inputs
def
rule_constr_u_limit_dim
(
m
,
i
,
m_i
,
q
,
k
):
return
(
m
.
var_u_imqk
[(
i
,
m_i
,
q
,
k
)]
<=
m
.
var_u_amp_im
[(
i
,
m_i
)]
*
m
.
param_f_amp_u_imqk
[(
i
,
m_i
,
q
,
k
)]
)
model
.
constr_u_limit_dim
=
pyo
.
Constraint
(
model
.
set_IM_dim
,
model
.
set_QK
,
rule
=
rule_constr_u_limit_dim
)
# nominal input amplitude limit for dimensionable inputs
def
rule_constr_u_amp_ub
(
m
,
i
,
m_i
):
return
(
m
.
var_u_amp_im
[(
i
,
m_i
)]
<=
m
.
var_cvt_inv_i
[
i
]
*
m
.
param_u_amp_max_im
[(
i
,
m_i
)]
)
model
.
constr_u_amp_ub
=
pyo
.
Constraint
(
model
.
set_IM_dim
,
rule
=
rule_constr_u_amp_ub
)
# fixed upper limits
def
rule_constr_u_fix_limits
(
m
,
i
,
m_i
,
q
,
k
):
# if we need to know the lim input signal (e.g., for the obj. func.)
if
i
in
m
.
set_I_new
:
# new converter
return
(
m
.
var_u_imqk
[(
i
,
m_i
,
q
,
k
)]
<=
m
.
param_u_ub_imqk
[(
i
,
m_i
,
q
,
k
)]
*
m
.
var_cvt_inv_i
[
i
]
)
return
m
.
var_u_imqk
[(
i
,
m_i
,
q
,
k
)]
<=
m
.
var_cvt_inv_i
[
i
]
else
:
# pre-existing
return
m
.
var_u_imqk
[(
i
,
m_i
,
q
,
k
)]
<=
m
.
param_u_ub_imqk
[(
i
,
m_i
,
q
,
k
)]
model
.
constr_u_fix_limits
=
pyo
.
Constraint
(
model
.
set_IM_fix
,
model
.
set_QK
,
rule
=
rule_constr_u_fix_limits
)
# input limits for binary inputs
def
rule_constr_u_bin_limits
(
m
,
i
,
m_i
,
q
,
k
):
if
i
in
m
.
set_I_new
:
# binary variables
return
m
.
var_u_imqk
[(
i
,
m_i
,
q
,
k
)]
<=
m
.
var_cvt_inv_i
[
i
]
else
:
return
pyo
.
Constraint
.
Skip
model
.
constr_u_bin_limits
=
pyo
.
Constraint
(
model
.
set_IM_bin
,
model
.
set_QK
,
rule
=
rule_constr_u_bin_limits
)
# *************************************************************************
# outputs
# output equations
def
rule_constr_output_equations
(
m
,
i
,
r
,
q
,
k
):
return
(
m
.
var_y_irqk
[(
i
,
r
,
k
)]
==
sum
(
m
.
param_c_eq_y_irnqk
[(
i
,
r
,
n_i
,
q
,
k
)]
*
m
.
var_x_inqk
[(
i
,
n_i
,
q
,
k
)]
for
n_i
in
m
.
set_N
[
i
]
)
+
sum
(
m
.
param_d_eq_y_irmqk
[(
i
,
r
,
m_i
,
q
,
k
)]
*
m
.
var_u_imqk
[(
i
,
m_i
,
q
,
k
)]
for
m_i
in
m
.
set_M
[
i
]
)
+
m
.
param_e_eq_y_irqk
[(
i
,
r
,
q
,
k
)]
)
model
.
constr_output_equations
=
pyo
.
Constraint
(
model
.
set_IR
,
model
.
set_QK
,
rule
=
rule_constr_output_equations
)
# positive amplitude limit for output variables
def
rule_constr_y_vars_have_pos_amp_limits
(
m
,
i
,
r
,
q
,
k
):
return
m
.
var_y_irqk
[(
i
,
r
,
q
,
k
)]
<=
(
m
.
var_y_amp_pos_ir
[(
i
,
r
)]
*
m
.
param_f_amp_y_pos_irqk
[(
i
,
r
,
q
,
k
)]
)
model
.
constr_y_vars_have_pos_amp_limits
=
pyo
.
Constraint
(
model
.
set_IR_dim_pos
,
model
.
set_QK
,
rule
=
rule_constr_y_vars_have_pos_amp_limits
)
# negative amplitude limit for output variables
def
rule_constr_y_vars_have_neg_amp_limits
(
m
,
i
,
r
,
q
,
k
):
return
m
.
var_y_irqk
[(
i
,
r
,
q
,
k
)]
>=
(
-
m
.
var_y_amp_neg_ir
[(
i
,
r
)]
*
m
.
param_f_amp_y_neg_irqk
[(
i
,
r
,
q
,
k
)]
)
model
.
constr_y_vars_have_neg_amp_limits
=
pyo
.
Constraint
(
model
.
set_IR_dim_neg
,
model
.
set_QK
,
rule
=
rule_constr_y_vars_have_neg_amp_limits
)
# positive amplitude limit must be zero unless the system is installed
def
rule_constr_y_amp_pos_zero_if_cvt_not_selected
(
m
,
i
,
r
):
return
m
.
var_y_amp_pos_ir
[(
i
,
r
)]
<=
(
m
.
var_cvt_inv_i
[
i
]
*
m
.
param_y_amp_pos_ir
[(
i
,
r
)]
)
model
.
constr_y_amp_pos_zero_if_cvt_not_newected
=
pyo
.
Constraint
(
model
.
set_IR_dim_pos
,
rule
=
rule_constr_y_amp_pos_zero_if_cvt_not_selected
)
# negative amplitude limit must be zero unless the system is installed
def
rule_constr_y_amp_neg_zero_if_cvt_not_selected
(
m
,
i
,
r
):
return
m
.
var_y_amp_neg_ir
[(
i
,
r
)]
<=
(
m
.
var_cvt_inv_i
[
i
]
*
m
.
param_y_amp_neg_ir
[(
i
,
r
)]
)
model
.
constr_y_amp_neg_zero_if_cvt_not_selected
=
pyo
.
Constraint
(
model
.
set_IR_dim_neg
,
rule
=
rule_constr_y_amp_neg_zero_if_cvt_not_selected
)
# the positive and negative amplitudes must match
def
rule_constr_y_amp_pos_neg_match
(
m
,
i
,
r
):
return
m
.
var_y_amp_pos_ir
[(
i
,
r
)]
==
m
.
var_y_amp_neg_ir
[(
i
,
r
)]
model
.
constr_y_amp_pos_neg_match
=
pyo
.
Constraint
(
model
.
set_IR_dim_eq
,
rule
=
rule_constr_y_amp_pos_neg_match
)
# *************************************************************************
# states
def
rule_constr_state_equations
(
m
,
i
,
n
,
q
,
k
):
return
(
m
.
var_x_inqk
[(
i
,
n
,
q
,
k
)]
==
sum
(
m
.
param_a_eq_x_innqk
[(
i
,
n
,
n_star
,
q
,
k
)]
*
(
m
.
var_x_inqk
[(
i
,
n_star
,
q
,
k
-
1
)]
if
k
!=
0
else
m
.
param_x_inq0
[(
i
,
n
,
q
)]
)
for
n_star
in
m
.
set_N
[
i
]
)
+
sum
(
m
.
param_b_eq_x_inmqk
[(
i
,
n
,
m_i
,
q
,
k
)]
*
m
.
var_u_imqk
[(
i
,
m_i
,
q
,
k
)]
for
m_i
in
m
.
set_M
[
i
]
)
+
m
.
param_e_eq_x_inqk
[(
i
,
n
,
q
,
k
)]
)
model
.
constr_state_equations
=
pyo
.
Constraint
(
model
.
set_IN
,
model
.
set_QK
,
rule
=
rule_constr_state_equations
)
# positive amplitude limit for state variables
def
rule_constr_x_vars_have_pos_amp_limits
(
m
,
i
,
n
,
q
,
k
):
return
m
.
var_x_inqk
[(
i
,
n
,
q
,
k
)]
<=
(
m
.
var_x_amp_pos_in
[(
i
,
n
)]
*
m
.
param_f_amp_x_pos_inqk
[(
i
,
n
,
q
,
k
)]
)
model
.
constr_x_vars_have_pos_amp_limits
=
pyo
.
Constraint
(
model
.
set_IN_dim_pos
,
model
.
set_QK
,
rule
=
rule_constr_x_vars_have_pos_amp_limits
)
# negative amplitude limit for state variables
def
rule_constr_x_vars_have_neg_amp_limits
(
m
,
i
,
n
,
q
,
k
):
return
m
.
var_x_inqk
[(
i
,
n
,
q
,
k
)]
>=
(
-
m
.
var_y_amp_neg_in
[(
i
,
n
)]
*
m
.
param_f_amp_x_neg_inqk
[(
i
,
n
,
q
,
k
)]
)
model
.
constr_x_vars_have_neg_amp_limits
=
pyo
.
Constraint
(
model
.
set_IN_dim_neg
,
model
.
set_QK
,
rule
=
rule_constr_x_vars_have_neg_amp_limits
)
# positive amplitude limit must be zero unless the system is installed
def
rule_constr_x_amp_pos_zero_if_cvt_not_selected
(
m
,
i
,
n
):
return
m
.
var_x_amp_pos_in
[(
i
,
n
)]
<=
(
m
.
var_cvt_inv_i
[
i
]
*
m
.
param_x_amp_pos_in
[(
i
,
n
)]
)
model
.
constr_x_amp_pos_zero_if_cvt_not_selected
=
pyo
.
Constraint
(
model
.
set_IN_dim_pos
,
rule
=
rule_constr_x_amp_pos_zero_if_cvt_not_selected
)
# negative amplitude limit must be zero unless the system is installed
def
rule_constr_x_amp_neg_zero_if_cvt_not_selected
(
m
,
i
,
n
):
return
m
.
var_x_amp_neg_in
[(
i
,
n
)]
<=
(
m
.
var_cvt_inv_i
[
i
]
*
m
.
param_x_amp_neg_in
[(
i
,
n
)]
)
model
.
constr_x_amp_neg_zero_if_cvt_not_selected
=
pyo
.
Constraint
(
model
.
set_IN_dim_neg
,
rule
=
rule_constr_x_amp_neg_zero_if_cvt_not_selected
)
# the positive and negative amplitudes must match
def
rule_constr_x_amp_pos_neg_match
(
m
,
i
,
n
):
return
m
.
var_x_amp_pos_in
[(
i
,
n
)]
==
m
.
var_x_amp_neg_in
[(
i
,
n
)]
model
.
constr_x_amp_pos_neg_match
=
pyo
.
Constraint
(
model
.
set_IN_dim_eq
,
rule
=
rule_constr_x_amp_pos_neg_match
)
# *************************************************************************
# *************************************************************************
return
model
# *************************************************************************
# *************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
# *****************************************************************************
Loading