Infeasible solution with a lower bound on a flow (otherwise bigger than the limit)

I have a problem with a simple transformer or with the flows connecting it with the bus it generates or the bus it consumes: if I put no lower bound on the in-/out-flow, the activity of the transformer is bigger than zero in a particular time-step (it consumes and produces some energy); but if I put a lower bound on the in-flow or out-flow - even much lower than the value it assumes without the bound - then, the solver cannot find any optimal solution!
There is an active upper bound on the same flow, however there shouldn’t be any conflict between the two, because the upper bound is bigger than the lower one in any time-step (the max value is bigger than the min value and the capacity-in equals the capacity-out; efficiency is 1). Moreover, the problem exists also when I remove the upper bound.
I get the infeasibility with any range of time-steps I consider (actually I haven’t tried all the combinations of the 8760 timesteps, it’s my conclusion based on few combinations).
I tried to get some more information on the issue by adding a “shortage” transformer producing the same bus. The solver found a solution but the bus is produced only by the shortage transformer, even with a very high cost. It seems to me this particular transformer cannot work at all when there is a lower bound on its in-/out-flow.
I use the min and max bounds also on other flows/transformers, and they all work properly.
Furthermore, with om.pprint() I see that the flow is properly considered in the equations.
Am I missing anything? Has anyone experienced anything similar?

I’m using the “def nodes_from_excel(filename)”
Here is the interested portion of code:

[…]

timeseries = xls.parse('time_series')
distributed_PV = xls.parse('distributed_PV')
     
for i, t in distributed_PV.iterrows():
        noded[i] = solph.Transformer(
            label=i,
            inputs={
                noded[t['from']]: solph.Flow(
                    nominal_value=t['capacity [MW]'])},
            outputs={
                noded[t['bus']]: solph.Flow(
                    nominal_value=t['capacity [MW]'],
                    min = timeseries[i],
                    max = timeseries['it_solar_pv_s_fix'])})

[…]

the distributed_PV xls sheet content is as follows:

     		from		        bus		   capacity [MW]
it_PV_use	it_bus_PV_use	it_bus_el_t&d	10440

and the timeseries for the first three time-steps are:
it_PV_use
0.0752
0.0721
0.0676
it_solar_pv_s_fix
0.0100
0.0100
0.0100

I do not fully understand your general modelling idea.

Why do you use a Transformer for pv? Normally a pv-source is modelled by a source:

solph.Source(label='pv1', outputs={electricity_bus: solph.Flow(
    actual_value=pv_feedin_time_series, nominal_value=10440, fixed=True)})

solph.Source(label='pv2', outputs={electricity_bus: solph.Flow(
    max=pv_feedin_time_series, nominal_value=10440)})

In the first case (pv1) you need an excess sink for excess energy. The good thing is that you can sum up the excess in the results to get the unused energy. In the second case (pv2) you do not need an excess sink but it is a little bit more complicated to get the amount of unused energy.

Of course it is also possible to use a Transformer but I do not understand the idea.

If I get it right the max value is 0.01 while the min values varies (0.0752, 0.0721, 0.0676). This is infeasible because the maximum is lower than the minimum. If you do not set a minimum but a maximum the flow will be between zero and the maximum.

You defined the nominal value in the input and(!) the output flow. It is less error prune to define every value just once.

Dear Uwe,

Thank you for the very fast reply.

About how to model PV:
I do use sources for other PV plants. In the mentioned case however I use some dummy transformers and a storage to simulate small distributed PV plants combined with batteries. The overall set of dummy transformers + storage is used to distinguish direct self-consumption (bypassing the efficiency of batteries), self-consumption passing through the batteries, and electricity forwarded to the grid.
I’m not sure this is the best way to do this - I’m studying it.
I cannot put all the details of the model and I’m sorry if this generated confusion.

About the timeseries I use:
actually they are the opposite of what I wrote by mistake in the question (I’m sorry for the additional confusion):

it_PV_use
0.0100
0.0100
0.0100

it_solar_pv_s_fix
0.0752
0.0721
0.0676

So, to summarise:
(i) - the min is lower than the max
(ii) - the min is lower than the value found by the solver (cbc) without lower bound

Thank you for the suggestion about defining only the output or input nominal value. I agree, but the infeasibility persists!

I still do not understand want you want.

If it is possible to solve the model without the minimal value but infeasible with the minimal I guess it has something to do with the minimal value. I do not know enough about your model but maybe there is one time step where the minimal of 0.01 is not possible.

But if the minimal value is just an idea to solve the original problem you should talk about the original problem. Normally adding very high priced sources and sinks make problems feasible and make the debugging easier. I do not know what went wrong in your case, because I do not know you problem.

You should think of all constraint build by your problem and step by step check if every component is doing what you expect it to do.

You should model just a few time steps and check the LP file for debugging.

I solved the problem:
Upstream the mentioned transformer there is a storage (among other transformers) and its initial capacity is different from zero. None of the run I did ( with 8760, 72, 24, 12, 4, 3 timesteps) was succesfull with the min > 0 because the final capacity of the storage could not reach the initial value. Without the min, the activity of the mentioned transformer resulted in non-zero values in the first few time steps, but only when I considered 8760, 72, 24 and 12 timesteps. I didn’t check it for the runs with 4 and 3, and this was the biggest mistake in this story.

If this topic can be converted into something useful for other users, I think the main lesson is: one reason for the solver not to find a solution is “there might be a storage somewhere not able to reach its initial capacity at the end of the period”

@Uwe - I think you are perfectly right when you say

“if the minimal value is just an idea to solve the original problem you should talk about the original problem”

For the sake of completeness, here is te original problem:
I would like to model the distributed PV-battery systems as a whole single aggregated storage. However I don’t want the system to consider it similarly to a big centralized storage connected to PV generation (exploitable whenever convenient to the whole system). So, the approach is to constrain the dummy transformer (that simulates the self-consumption) in order to exogenously drive its activity but leaving it little degree of freedom.

Thanks again!

I am glad to hear that. You can mark your own post or any other as solution to mark this topic as solved.

In the next release you will be able to set balanced=False. We are revising the storage class. Maybe we can add your warning to the storage documentation.

To see the upcoming changes you could have a look at github.

1 Like