-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Models with stock #33
base: main
Are you sure you want to change the base?
Changes from 30 commits
5b72beb
7465997
8b687c6
966b4de
927cc47
18a4b1f
d0e8e26
82efdad
4400c46
51de9e4
ffcc3de
dc08c71
f6218bd
25b567f
f5a0eec
d7ce092
fccf367
006131b
cddd635
25d4b79
7739a77
ed4f8a0
4b949d6
f912f0d
b3ed8e7
b4a1bd1
eb30fbc
564d10f
7b9fb16
651ca02
14bc1e5
e668672
24d0c06
6e16230
8fba186
5bfdfcc
3765536
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -211,3 +211,56 @@ | |||||
) | ||||||
], | ||||||
) | ||||||
|
||||||
LINK_WITH_STORAGE = model( | ||||||
id="Link with storage model", | ||||||
parameters=[ | ||||||
float_parameter("f_from_max", CONSTANT), | ||||||
float_parameter("f_to_max", CONSTANT), | ||||||
float_parameter("capacity", CONSTANT), | ||||||
float_parameter("initial_level", CONSTANT), | ||||||
], | ||||||
variables=[ | ||||||
float_variable("r", lower_bound=literal(0), upper_bound=param("capacity")), | ||||||
float_variable( | ||||||
"f_from", lower_bound=-param("f_from_max"), upper_bound=param("f_from_max") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
), | ||||||
float_variable( | ||||||
"f_to", lower_bound=-param("f_to_max"), upper_bound=param("f_to_max") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
), | ||||||
float_variable("f_from+", lower_bound=literal(0)), | ||||||
float_variable("f_from-", lower_bound=literal(0)), | ||||||
float_variable("f_to+", lower_bound=literal(0)), | ||||||
float_variable("f_to-", lower_bound=literal(0)), | ||||||
], | ||||||
ports=[ | ||||||
ModelPort(port_type=BALANCE_PORT_TYPE, port_name="flow_from"), | ||||||
ModelPort(port_type=BALANCE_PORT_TYPE, port_name="flow_to"), | ||||||
ModelPort(port_type=BALANCE_PORT_TYPE, port_name="flow_from_pos"), | ||||||
ModelPort(port_type=BALANCE_PORT_TYPE, port_name="flow_to_pos"), | ||||||
], | ||||||
port_fields_definitions=[ | ||||||
PortFieldDefinition( | ||||||
port_field=PortFieldId("flow_from", "flow"), | ||||||
definition=-var("f_from"), | ||||||
), | ||||||
PortFieldDefinition( | ||||||
port_field=PortFieldId("flow_to", "flow"), | ||||||
definition=var("f_to"), | ||||||
), | ||||||
PortFieldDefinition( | ||||||
port_field=PortFieldId("flow_from_pos", "flow"), | ||||||
definition=var("f_from+"), | ||||||
), | ||||||
PortFieldDefinition( | ||||||
port_field=PortFieldId("flow_to_pos", "flow"), | ||||||
definition=var("f_to+"), | ||||||
), | ||||||
], | ||||||
constraints=[ | ||||||
Constraint( | ||||||
name="Level", | ||||||
expression=var("f_from") == (var("f_from+") - var("f_from-")), | ||||||
), | ||||||
], | ||||||
Comment on lines
+260
to
+265
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This model is incomplete (missing shift operators at least). Was it superseded by the yml ? If so, I suggest removing standard_sc.py completely. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes it seems to be superseeded by the model in the yml |
||||||
) |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some models are defined in local libraries for tests, delete the incomplete, unsed ones from here ( |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,112 @@ library: | |
- name: emission | ||
|
||
models: | ||
- id: link_with_storage | ||
description: A link with energy storage | ||
parameters: | ||
- name: f_from_max | ||
time-dependent: false | ||
scenario-dependent: false | ||
- name: f_to_max | ||
time-dependent: false | ||
scenario-dependent: false | ||
- name: capacity | ||
time-dependent: false | ||
scenario-dependent: false | ||
- name: initial_level | ||
time-dependent: false | ||
scenario-dependent: false | ||
variables: | ||
- name: r | ||
lower-bound: 0 | ||
upper-bound: capacity | ||
- name: f_from | ||
lower-bound: -f_from_max | ||
upper-bound: f_from_max | ||
- name: f_to | ||
lower-bound: -f_to_max | ||
upper-bound: f_to_max | ||
- name: f_from_p | ||
lower-bound: 0 | ||
- name: f_from_m | ||
lower-bound: 0 | ||
- name: f_to_p | ||
lower-bound: 0 | ||
- name: f_to_m | ||
lower-bound: 0 | ||
ports: | ||
- name: flow_from | ||
type: flow | ||
- name: flow_to | ||
type: flow | ||
- name: flow_from_pos | ||
type: flow | ||
- name: flow_to_pos | ||
type: flow | ||
port-field-definitions: | ||
- port: flow_from | ||
field: flow | ||
definition: -f_from | ||
- port: flow_to | ||
field: flow | ||
definition: f_to | ||
constraints: | ||
- name: max0_from | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. More explicit name : |
||
expression: f_from = f_from_p - f_from_m | ||
- name: max0_to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same |
||
expression: f_to = f_to_p - f_to_m | ||
- name: r_h | ||
expression: r[t+1] = r[t] + f_from - f_to | ||
binding-constraints: | ||
- name: FlowFromPos | ||
expression: sum_connections(flow_from_pos.flow) = f_from_p | ||
- name: FlowToPos | ||
expression: sum_connections(flow_to_pos.flow) = f_to_p | ||
|
||
- id: stock_final_level | ||
description: A stock model | ||
parameters: | ||
- name: p_max_in | ||
time-dependent: false | ||
scenario-dependent: false | ||
- name: p_max_out | ||
time-dependent: false | ||
scenario-dependent: false | ||
- name: capacity | ||
time-dependent: false | ||
scenario-dependent: false | ||
- name: initial_level | ||
time-dependent: false | ||
scenario-dependent: false | ||
- name: final_level | ||
time-dependent: false | ||
scenario-dependent: false | ||
variables: | ||
- name: r | ||
lower-bound: 0 | ||
upper-bound: capacity | ||
- name: u_in | ||
lower-bound: 0 | ||
upper-bound: p_max_in | ||
- name: u_out | ||
lower-bound: 0 | ||
upper-bound: p_max_out | ||
ports: | ||
- name: flow_s | ||
type: flow | ||
- name: flow_c | ||
type: flow | ||
port-field-definitions: | ||
- port: flow_s | ||
field: flow | ||
definition: u_out - u_in | ||
constraints: | ||
- name: r_h | ||
expression: r[t+1] = r[t] + u_in[t] - u_out[t] | ||
binding-constraints: | ||
- name: flow_in | ||
expression: sum_connections(flow_c.flow) = u_in | ||
|
||
- id: convertor | ||
description: A basic convertor model | ||
parameters: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
# Copyright (c) 2024, RTE (https://www.rte-france.com) | ||
# | ||
# See AUTHORS.txt | ||
# | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this | ||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
# | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# | ||
# This file is part of the Antares project. | ||
|
||
import math | ||
from pathlib import Path | ||
|
||
from andromede.simulation import OutputValues, TimeBlock, build_problem | ||
from andromede.study import ( | ||
ConstantData, | ||
DataBase, | ||
Network, | ||
Node, | ||
PortRef, | ||
create_component, | ||
) | ||
|
||
|
||
def test_gas_link_elec_compressor(data_dir: Path, lib: Path, lib_sc: Path): | ||
""" | ||
Test of a pipeline with stock capacity | ||
|
||
for the following test we have two gaz production and two gaz demands, | ||
One of each on each sides of a pipeline that has a storage capacity | ||
gaz_prod_1 and gaz_demand_1 are on the input side of the pipeline | ||
gaz_prod_2 and gaz_demand_2 are on the output side of the pipeline | ||
we have the following values: | ||
electricity production: | ||
- p_max = 200 | ||
- cost = 10 | ||
gaz production: | ||
- p_max = 300 | ||
- cost = 10 | ||
gaz demand: | ||
- demand = 100 | ||
electricity demand: | ||
- demand = 10 | ||
pipeline: | ||
- f_from_max = 100 | ||
- f_to_max = 50 | ||
- capacity = 100 | ||
- initial_level = 20 | ||
electrolyzer: | ||
- alpha = 0.5 | ||
compressor from: | ||
- alpha = 0.7 | ||
compressor to: | ||
- alpha = 0.7 | ||
""" | ||
gen_model = lib.models["generator"] | ||
node_model = lib.models["node"] | ||
demand_model = lib.models["demand"] | ||
link_with_storage_model = lib_sc.models["link_with_storage"] | ||
convertor_model = lib_sc.models["convertor"] | ||
|
||
gaz_node_1 = Node(model=node_model, id="g1") | ||
gaz_node_2 = Node(model=node_model, id="g2") | ||
elec_node = Node(model=node_model, id="e") | ||
gaz_prod = create_component(model=gen_model, id="pg") | ||
elec_prod = create_component(model=gen_model, id="pe") | ||
gaz_demand = create_component(model=demand_model, id="dg") | ||
elec_demand = create_component(model=demand_model, id="de") | ||
pipeline = create_component(model=link_with_storage_model, id="pp") | ||
electrolyzer = create_component(model=convertor_model, id="ez") | ||
compressor_from = create_component(model=convertor_model, id="cpf") | ||
compressor_to = create_component(model=convertor_model, id="cpt") | ||
|
||
database = DataBase() | ||
database.add_data("dg", "demand", ConstantData(100)) | ||
database.add_data("de", "demand", ConstantData(10)) | ||
|
||
database.add_data("pg", "p_max", ConstantData(300)) | ||
database.add_data("pg", "cost", ConstantData(10)) | ||
database.add_data("pe", "p_max", ConstantData(200)) | ||
database.add_data("pe", "cost", ConstantData(10)) | ||
|
||
database.add_data("pp", "f_from_max", ConstantData(100)) | ||
database.add_data("pp", "f_to_max", ConstantData(50)) | ||
database.add_data("pp", "capacity", ConstantData(100)) | ||
database.add_data("pp", "initial_level", ConstantData(20)) | ||
|
||
database.add_data("ez", "alpha", ConstantData(0.5)) | ||
|
||
database.add_data("cpf", "alpha", ConstantData(0.7)) | ||
database.add_data("cpt", "alpha", ConstantData(0.7)) | ||
|
||
network = Network("test") | ||
network.add_node(gaz_node_1) | ||
network.add_node(gaz_node_2) | ||
network.add_node(elec_node) | ||
network.add_component(gaz_prod) | ||
network.add_component(elec_prod) | ||
network.add_component(gaz_demand) | ||
network.add_component(elec_demand) | ||
network.add_component(pipeline) | ||
network.add_component(compressor_from) | ||
network.add_component(compressor_to) | ||
network.add_component(electrolyzer) | ||
|
||
network.connect( | ||
PortRef(gaz_node_2, "injection_port"), PortRef(gaz_prod, "injection_port") | ||
) | ||
network.connect(PortRef(gaz_node_2, "injection_port"), PortRef(pipeline, "flow_to")) | ||
network.connect(PortRef(gaz_node_2, "injection_port"), PortRef(pipeline, "flow_to")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as previous line.... |
||
|
||
network.connect( | ||
PortRef(gaz_node_1, "injection_port"), PortRef(gaz_demand, "injection_port") | ||
) | ||
network.connect( | ||
PortRef(gaz_node_1, "injection_port"), PortRef(pipeline, "flow_from") | ||
) | ||
network.connect( | ||
PortRef(gaz_node_1, "injection_port"), PortRef(electrolyzer, "output_port") | ||
) | ||
|
||
network.connect( | ||
PortRef(pipeline, "flow_from_pos"), PortRef(compressor_from, "output_port") | ||
) | ||
network.connect( | ||
PortRef(pipeline, "flow_to_pos"), PortRef(compressor_to, "output_port") | ||
) | ||
|
||
network.connect( | ||
PortRef(elec_node, "injection_port"), PortRef(elec_demand, "injection_port") | ||
) | ||
network.connect( | ||
PortRef(elec_prod, "injection_port"), PortRef(elec_node, "injection_port") | ||
) | ||
network.connect( | ||
PortRef(elec_node, "injection_port"), PortRef(electrolyzer, "input_port") | ||
) | ||
network.connect( | ||
PortRef(elec_node, "injection_port"), PortRef(compressor_from, "input_port") | ||
) | ||
network.connect( | ||
PortRef(elec_node, "injection_port"), PortRef(compressor_to, "input_port") | ||
) | ||
|
||
scenarios = 1 | ||
problem = build_problem(network, database, TimeBlock(1, [0]), scenarios) | ||
status = problem.solver.Solve() | ||
|
||
output = OutputValues(problem) | ||
r_value = output.component("pp").var("r").value | ||
generation1 = output.component("pg").var("generation").value | ||
generation2 = output.component("pe").var("generation").value | ||
print("generation") | ||
print(generation1) | ||
print(generation2) | ||
r = output.component("pp").var("r") | ||
print(r) | ||
assert status == problem.solver.OPTIMAL | ||
assert math.isclose(problem.solver.Objective().Value(), 2100) | ||
|
||
assert math.isclose(r_value, 100) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.