-
Notifications
You must be signed in to change notification settings - Fork 137
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
Building EnergySystem succeeds even if Flows point out #1148
Comments
I made sense out of this:
I think the solution would be to fail building the model if the Here is a shorter version of @fwitte's test cases including the explanation what actually happens in the cases he presented. For completeness, I added two cases (0 and 7). from oemof import solph
from oemof.solph import Bus
from oemof.solph import EnergySystem
from oemof.solph import Flow
from oemof.solph import Model
def solve_case(variation):
es = EnergySystem(
timeindex=solph.create_time_index(2024, number=3),
infer_last_interval=False,
)
source = Bus("source", balanced=False)
b1 = Bus("b1")
sink = Bus("sink", balanced=False)
b1.inputs[source] = Flow(nominal_value=2, fix=1, variable_costs=0.1)
match variation:
case 0:
es.add(source, b1, sink)
# infeasible: b1 cannot be balanced, as there is no Flow
case 1:
sink.inputs[b1] = Flow() # considered via b1 and sink
es.add(source, b1, sink)
# optimal
case 2:
sink.inputs[b1] = Flow() # still considered via b1
es.add(source, b1)
# optimal
case 3:
b2 = Bus("b2") # not considered
b2.inputs[b1] = Flow() # still considered via b1
sink.inputs[b2] = Flow(nominal_value=1) # not considered
es.add(source, b1)
# optimal
case 4:
b2 = Bus("b2") # considered
b2.inputs[b1] = Flow() # not considered
sink.inputs[b2] = Flow(nominal_value=1) # not considered
es.add(source, b1, b2)
# infeasible: b2 cannot be balanced (no Flow out)
case 5:
b2 = Bus("b2") # not considered
b2.inputs[b1] = Flow() # considered via b1
b2.outputs[sink] = Flow(nominal_value=1) # not considered
es.add(source, b1)
# optimal
case 6:
b2 = Bus("b2") # considered
b2.inputs[b1] = Flow() # considered
b2.outputs[sink] = Flow(nominal_value=1) # considered
es.add(source, b1, b2)
# infeasible: b2 cannot be balanced (Flow out too small)
case 7:
sink.inputs[b1] = Flow() # still considered via b1
es.add(b1)
# optimal
try:
model = Model(es) # will fail for case 7
solver_results = model.solve("cbc")
termination = solver_results["Solver"][0]["Termination condition"]
except:
termination = "unable to build"
print(variation, ": ", termination)
for variation in range(8):
solve_case(variation) |
I tried to check indirectly by creating a |
When forgetting to add elements to the
EnergySystem
(e.g. because you forgot) things happen, that look not intended.Consider the following very simple system:
The correct code would look like this:
Now, if you forgot to add the sink, the result is exactly the same. The model works and the
source
produces what is required by thesink
even though we did not add it to theEnergySystem
. This is in my opinion at least surprising, but does not need to be an actual issue.However, if you were to add more components in between, e.g. change to
then forgetting to add the Bus "b2" and the
sink
will add the flow of the Bus "b2" but will ignore theFlow
attached to the sink, which seems somehow inconsistent to the behavior above. The example below would lead to an infeasibility if all flows were considered:Changing this to the correct version:
Finally, to make things even more weird: If you put the flows as inputs and outputs of the Bus "b2" (and no `inputs´ for the sink), this model works fine, even though the input and output flows on Bus "b2" contradict in their constraints:
The infeasibility is only detected if the Bus "b2" is actually added to the
EnergySystem
:In my opinion, it would be better, if the
EnergySystem
would always ignore parts of the system if not explicitly added. What do you think?Edit by @p-snft: I allowed myself to enumerate the code snippets.
The text was updated successfully, but these errors were encountered: