-
Notifications
You must be signed in to change notification settings - Fork 238
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
Price taker model for DISPATCHES, Rehashed #1358
base: main
Are you sure you want to change the base?
Changes from 19 commits
a3d688c
67ce6a2
e716c36
e3788fb
8ef54be
f154700
422d0ba
2f36bbb
0aa1034
9042e5c
5549028
2fde47f
d0a6c13
e5f6c07
56d9369
9b5edd4
948f40c
30fed63
fc43a3f
4170501
1d87aea
4710a10
be68154
66db0d8
b39f4d9
799ed0b
7625d07
0c2c461
16710a6
4518240
35ddead
fd15af9
b84ea43
15ea641
53e427e
14ee544
4e10801
d68d8fd
6cd966e
f7e3245
b223cf6
56f8099
48d4d98
fde3f31
5bd0d5b
0df8b45
fd595b4
a54c3ac
70cbaba
85b7bd0
9851b88
6ede14e
d31b272
769ba7b
0bba4d2
b06d467
0cf82bf
6af8c9e
1fc5f53
e991392
f2725cc
522023b
22dbe12
6dbb183
7a86d03
7a24fba
b1629eb
d193e65
fb543c7
460af99
c90bbe1
643707f
8aa02c6
323e4a9
04d07ae
4ae5779
893743d
82f8bdc
ebdc1b2
aad41fb
e2dac86
5ad727e
2ae4635
8762f7b
7110dea
8550569
69c3c9b
177618c
ce4b0fb
343d191
cec302e
652d1cc
d8ade5d
cd3f3d3
ce6b3db
f4cfbdb
cbd7aaa
f10ea59
46a3331
7bdd94d
1c85981
6956d73
8b4b479
646b88b
a1f1eb2
8101448
d8de0dd
fc7369e
75a56f4
df687af
47b66c5
8ac5987
d10b9a7
1e7842a
8b1393a
6481545
b9f3ef4
bd2db6f
9cf4a3a
112761f
fb0a05b
5d960a4
d7a0002
727be78
aebe5b8
411bb60
bd3244c
b8149b5
043ac34
2cd22e4
e9ff144
422ec6e
042a1d9
0fd8edb
892e555
a2c97c4
20db58f
a4620de
a1ae6b7
bef17fb
59322da
994e936
07e56f7
fd3e227
796134c
c631948
87b68df
98a0faf
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 |
---|---|---|
|
@@ -10,27 +10,63 @@ | |
# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md | ||
# for full copyright and license information. | ||
################################################################################# | ||
from functools import reduce | ||
from pyomo.environ import ( | ||
Var, | ||
Param, | ||
Binary, | ||
Expression, | ||
NonNegativeReals, | ||
Constraint, | ||
) | ||
from pyomo.common.config import ConfigValue, In | ||
|
||
import logging | ||
from pyomo.environ import Binary, Param, Var | ||
from pyomo.common.config import Bool, ConfigDict, ConfigValue | ||
from idaes.core.base.process_base import declare_process_block_class | ||
from idaes.core.base.process_base import ProcessBlockData | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
# pylint: disable = attribute-defined-outside-init, too-many-ancestors | ||
# pylint: disable = invalid-name, logging-fstring-interpolation | ||
@declare_process_block_class("DesignModel") | ||
class DesignModelData(ProcessBlockData): | ||
""" | ||
Class for containing design model ... | ||
Builds the 'design model' for a unit/process. | ||
|
||
Args: | ||
model_func: Function that builds the design model | ||
model_args: Dictionary containing the arguments needed for model_func | ||
|
||
The class defines `install_unit` binary variable that takes the value 1 | ||
if the unit is built/installed, and 0 otherwise. | ||
|
||
Function model_func must declare all the necessary design variables, | ||
relations among design variables, capital cost correlations, and fixed O&M | ||
cost correlations. The function must also define attributes `capex` for | ||
capital cost, and `fom` for fixed O&M cost. If not defined, these attributes | ||
will be set to zero. | ||
|
||
Example Usage: | ||
|
||
.. code-block:: python | ||
|
||
def my_design_model(m, p_min, p_max, cost): | ||
m.power = Var() | ||
m.min_capacity = Constraint( | ||
expr=p_min * m.install_unit <= m.power | ||
) | ||
m.max_capacity = Constraint( | ||
expr=m.power <= p_max * m.install_unit | ||
) | ||
|
||
# capex and fom must either be a constant, or Var, or Expression | ||
m.capex = Expression(expr=cost["capex"] * m.power) | ||
m.fom = Expression(expr=cost["fom"] * m.power) | ||
|
||
m = ConcreteModel() | ||
m.unit_1 = DesignModel( | ||
model_func=my_design_model, | ||
model_args={ | ||
"p_min": 150, "p_max": 600, "cost": {"capex": 10, "fom": 1}, | ||
}, | ||
) | ||
Comment on lines
+28
to
+66
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. @andrewlee94 - documentation for design model |
||
""" | ||
|
||
CONFIG = ProcessBlockData.CONFIG() | ||
CONFIG = ConfigDict() | ||
CONFIG.declare( | ||
"model_func", | ||
ConfigValue( | ||
|
@@ -45,20 +81,74 @@ class DesignModelData(ProcessBlockData): | |
), | ||
) | ||
|
||
# noinspection PyAttributeOutsideInit | ||
def build(self): | ||
super().build() | ||
|
||
self.install_unit = Var( | ||
within=Binary, | ||
doc="Binary: 1, if the unit is installed, 0 otherwise", | ||
) | ||
|
||
if self.config.model_func is None: | ||
# Function that builds the design model is not specified | ||
return | ||
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. What is the expected behaviour/usage in this case? I note that if this occurs then none of the following code will run, and I do not see any documentation or messages about what this would mean for the user. I think a logger message is required here at the least. 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. I agree that we should add a logger message here. 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. I've addressed this already, but feel free to comment on the warning itself |
||
|
||
# Call the function that builds the design model | ||
self.config.model_func(self, **self.config.model_args) | ||
adam-a-a marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Check if capital and fixed O&M costs are defined | ||
if not hasattr(self, "capex"): | ||
_logger.warning( | ||
f"'capex' attribute is not set for the design model " | ||
f"{self.name}. Setting the capital cost of the unit to zero." | ||
) | ||
self.capex = 0 | ||
|
||
if not hasattr(self, "fom"): | ||
_logger.warning( | ||
f"'fom' attribute is not set for the design model " | ||
f"{self.name}. Setting the fixed O&M cost of the unit to zero." | ||
) | ||
self.fom = 0 | ||
|
||
|
||
@declare_process_block_class("OperationModel") | ||
class OperationModelData(ProcessBlockData): | ||
""" | ||
Class for containing design model ... | ||
Builds the 'operation model' for a unit/process. | ||
|
||
Args: | ||
model_func: Function that builds the operation model | ||
model_args: Dictionary containing the arguments needed for model_func | ||
|
||
The class defines `op_mode`, `startup`, and `shutdown` binary variables | ||
to track the operation, startup, and shutdown of the unit/process. | ||
|
||
Function model_func must declare all the necessary operation variables, | ||
relations among operation variables, and variable O&M cost correlations. | ||
|
||
Example Usage: | ||
|
||
.. code-block:: python | ||
|
||
def my_operation_model(m, design_blk): | ||
m.power = Var() | ||
m.fuel_flow = Var() | ||
... | ||
|
||
m = ConcreteModel() | ||
m.unit_1 = DesignModel( | ||
model_func=my_design_model, | ||
model_args={ | ||
"p_min": 150, "p_max": 600, "cost": {"capex": 10, "fom": 1}, | ||
}, | ||
) | ||
m.op_unit_1 = OperationModel( | ||
model_func=my_operation_model, model_args={"design_blk": m.unit_1}, | ||
) | ||
""" | ||
|
||
CONFIG = ProcessBlockData.CONFIG() | ||
CONFIG = ConfigDict() | ||
CONFIG.declare( | ||
"model_func", | ||
ConfigValue( | ||
|
@@ -72,20 +162,19 @@ class OperationModelData(ProcessBlockData): | |
doc="Dictionary containing arguments needed for model_func", | ||
), | ||
) | ||
|
||
CONFIG.declare( | ||
"declare_op_vars", | ||
ConfigValue( | ||
default=True, | ||
domain=In([True, False]), | ||
domain=Bool, | ||
doc="Should op_mode, startup, shutdown vars be defined?", | ||
), | ||
) | ||
CONFIG.declare( | ||
"append_lmp_data", | ||
"declare_lmp_param", | ||
ConfigValue( | ||
default=True, | ||
domain=In([True, False]), | ||
domain=Bool, | ||
doc="Should LMP data automatically be appended to the model?", | ||
), | ||
) | ||
|
@@ -98,24 +187,29 @@ def build(self): | |
if self.config.declare_op_vars: | ||
self.op_mode = Var( | ||
within=Binary, | ||
doc="Binary var: 1 if the unit is operating, 0 otherwise", | ||
doc="Binary: 1 if the unit is operating, 0 otherwise", | ||
) | ||
|
||
self.startup = Var( | ||
within=Binary, | ||
doc="Binary var: 1 if the startup is initiated, 0 otherwise", | ||
doc="Binary: 1 if the startup is initiated, 0 otherwise", | ||
) | ||
|
||
self.shutdown = Var( | ||
within=Binary, | ||
doc="Binary var: 1 if the shutdown is initiated, 0 otherwise", | ||
doc="Binary: 1 if the shutdown is initiated, 0 otherwise", | ||
) | ||
|
||
if self.config.append_lmp_data: | ||
if self.config.declare_lmp_param: | ||
self.LMP = Param( | ||
initialize=1, | ||
mutable=True, | ||
doc="Parameter: Will be updated to LMP value at given time", | ||
doc="Time-varying locational marginal prices (LMPs) [in $/MWh]", | ||
) | ||
|
||
if self.config.model_func is None: | ||
# Function that builds the operation model is not specified | ||
return | ||
MarcusHolly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Call the function that builds the operation model | ||
self.config.model_func(self, **self.config.model_args) | ||
radhakrishnatg marked this conversation as resolved.
Show resolved
Hide resolved
|
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.
Why are these necessary? It is generally bad practice to do blanket disabling of pylint warnings, and by doing this I cannot see what was the cause of the warning to suggest how to fix it.
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.
I agree with @andrewlee94. My suggestion: