-
Notifications
You must be signed in to change notification settings - Fork 134
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
Features/schedule for flow #666
base: dev
Are you sure you want to change the base?
Conversation
It can be important to determine the output of e.g. a CHP by a given schedule. In practice it´s used to fulfill contracts.
New parameters for class `Flow` has been added. They had to be added to the existing test files too.
Now it`s possible to fix the flow to a schedule with possible None values. If schedule is None for the certain timestep, flow will freely be calculated without any penalty constraints.
The implementation for penalty terms for scheduled flows is finished. * Maybe set a reasonable default value for penalty terms (penalty_pos and penalty_neg), but this acquires mathematical research.
Hello @c-koehl! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:
Comment last updated at 2022-06-24 14:12:31 UTC |
If you're interested, I could also add an example to oemof-examples. |
Once you're done with the implementation, select a reviewer who cross-checks the newly added code. Preferably, select someone who already has some context about this |
@gplssm I'm done with the implementation, but it seems like I don't have the rights to select a reviewer or labels. I don't know what I'm doing wrong? Also I cannot tell, which reviewer is the best to choose |
I'm not too familiar with permissions granted to individual devs. Maybe @uvchik can help out here. Meanwhile, I can request a review for you. Did you talk to anyone before/during your implementation of "schedule for flow"? I would prefer to select this person then. |
@gplssm I actually didn't talk to anyone. I would suggest a reviewer with mathematical optimization knowledge, but I think my procedure is also comprehensible for non mathematicians. |
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.
Thanks for the new feature. Looks great, I just added some minor comments regarding naming etc. But from my side, this looks quite good.
oemof/solph/blocks.py
Outdated
slack_pos : | ||
Difference of a flow to schedule in consecutive timesteps if flow | ||
has deficit to schedule. Indexed by SCHEDULE_FLOWS, TIMESTEPS. | ||
|
||
slack_neg : |
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.
Maybe these could be named to schedule_slack_pos, but I am not sure...It's also fine for me like this. Naming is always so controversial ;-)
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 like your idea. It is always better to be a little bit more specific and if we put "schedule" into the variable names, everybody knows where they belong to.
oemof/solph/network.py
Outdated
penalty term will be activated. If array-like, values can be None | ||
for flexible, non-fixed flow during the certain timestep. Used in |
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.
Does this work actually, i.e. setting someting like schedule=[1, 2, None, 3]
. Has this been tested. I thought pyomo would give an error if None is provided in the equation. Please check if to be sure.
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 tested it and it worked. But I'm confused now, because you're actually right. Usually pyomo is not amused if None is provided. I will add a "return Constraint.Skip" for completeness
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.
Ah I think it is possible, because of BuildAction no return value has to be provided and the constraints will be added by add() function.
I remember pyomo did expect a return value (and throws an error if you provide None) if you build constraints without BuildAction.
Maybe with BuildAction it does not expect anything and is fine with only executing the add() function. But I am honestly just guessing, because the documentary of pyomo's BuildAction is not very detailed.
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.
Ok, I tried adding the return value Constraints.Skip, but as soon as it will be returned once, pyomo quits the constraint completely and continues with the next constraint. So in your case (schedule = [1, 2, None, 3]), the flow will only follow the schedule until the first None: [1, 2, None]. Everything following the first None will not be handled.
Interesting, Constraint.Skip behaves differently when building constraints with BuildAction compared to without.
oemof/solph/network.py
Outdated
penalty term will be activated. If array-like, values can be None | ||
for flexible, non-fixed flow during the certain timestep. Used in | ||
combination with :attr:`penalty_pos` and :attr:`penalty_neg`. | ||
penalty_pos : numeric (sequence or scalar) |
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.
Should there be a high default value of something like 10e9 force the schedule kind of by default?
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 was also thinking about adding a default value. It's actually more user friendly. I think it depends on what kind of users are working with oemof. Do you think it will be necessary? I can easily add one :-)
oemof/solph/network.py
Outdated
sequences = ['actual_value', 'variable_costs', 'min', 'max'] | ||
sequences = ['actual_value', 'variable_costs', 'min', 'max', | ||
'schedule', 'penalty_neg', 'penalty_pos'] | ||
dictionaries = ['positive_gradient', 'negative_gradient'] | ||
defaults = {'fixed': False, 'min': 0, 'max': 1, 'variable_costs': 0, | ||
'positive_gradient': {'ub': None, 'costs': 0}, | ||
'negative_gradient': {'ub': None, 'costs': 0}, | ||
'penalty_neg': 0, 'penalty_pos': 0, 'schedule': None |
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 was thinking if this could not rather be implemented like the gradient cost stuff as a dictionary to reduced number of attributes. It seems better to me, but again-> there are always multiple ways. Maybe ask @gnn for this
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.
Sorry for taking so long to review this one... :-/
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.
Hmmm I do not know about this one. I personally think it can be helpful, if the user can determine during what timesteps he will punish the system harder or being more "relaxed" if flow can not follow the schedule.
No worries, we are all busy and even holidays were in between :-)
Update upstream dev branch
Deleted line with todo from older oemof version
I do not know how to un - fail these tests. I am not sure if they were caused by me... Please correct me if I am wrong |
Added a schedule for Flow
Functionality
Sometimes it´s important to set a schedule for a flow (e.g. CHP electrical output), e.g. for fulfilling contracts. During optimization flow will be pushed to fulfill the schedule, if possible. If it´s not possible a penalty term will be activated and added to the objective expression for each unit of the difference flow-schedule.
Changes made in oemof.solph.network
Parameter added to class Flow:
Flow has to follow the schedule, but LP won´t be infeasible, if flow can´t fulfill schedule: slack variables will be added (see Changes made in solph.blocks)
Describes the costs associated with one unit of the deficit of the flow (:= slack_pos) compared to the schedule. Costs will be added to the objective expression.
Describes the costs associated with one unit of the excessed flow (:= slack_neg). Will be added to the objective expression.
Changes made in oemof.solph.blocks
Added Set and Variables to class Flow:
SCHEDULE_FLOWS (pyomo.Set)
contains all flows with schedules
slack_neg (pyomo.Var, within=NonNegativeReals)
slack variable for representing excess of flow compared to schedule (see Added constraint to class Flow)
slack_pos (pyomo.Var, within=NonNegativeReals)
slack variable for representing deficit of flow compared to schedule
Added constraint to class Flow
Term added to objective expression:
Changes made in oemof.tests.test_processing
New Parameters of class Flow had to be added to the test file as well.
Changes made in oemof.tests.constraint_tests
Test for scheduled flow was added.
Changes made in oemof.tests.lp_files.flow_schedule.lp
Created file.
Changes made in doc.whatsnew.v0-3-3.rst
Created file.
Possible Improvements