Converter and avoiding nonConvex

Hello everyone

I am trying to model a small island system that contains PV, Wind and Battery storage as investment candidates. I have also set up a Diesel generator using the OffsetConverter to account for the non static efficiency. But this introduces the NonConvexity and turns the problem to an MILP. I have tried solving the model with Gurobi but even for a small system like mine it cant find a solution for a one year optimization (takes 2-3 days and then my laptop runs out of memory).

Do you have any suggestions on how to avoid this issue? I thought about using the PiecewiseLinearConverter but I am not sure if it will solve this issue if i try to capture the efficiency curve using a function. I am also not sure if I can implement a min_load for the generator either (meaning that I dont want it to operate below 50% capacity if it needs to operate)

Any help/suggestions would be appreciated

PS: Here is the Offset converter definition and the model size from Gurobi

Optimize a model with 113889 rows, 105131 columns and 293519 nonzeros
Model fingerprint: 0x7900b732
Variable types: 96371 continuous, 8760 integer (8760 binary)
Coefficient statistics:
Matrix range [1e-03, 1e+03]
Objective range [1e-01, 1e+05]
Bounds range [1e+00, 1e+05]
RHS range [7e-01, 4e+00]
Presolve removed 43811 rows and 52569 columns
Presolve time: 1.03s
Presolved: 70078 rows, 52562 columns, 188377 nonzeros
Variable types: 43802 continuous, 8760 integer (8760 binary)
Deterministic concurrent LP optimizer: primal and dual simplex
Showing primal log only…

elif diesel_gen_type ==2:
    min_load = 0.5
    max_load = 1.0
    min_efficiency = 0.299
    max_efficiency = 0.3698
    
    c1 = (max_load / max_efficiency - min_load / min_efficiency) / (
        max_load - min_load
    )
    c0 = min_load * (1 / min_efficiency - c1)
    
    diesel_generator = solph.components.OffsetConverter(
        label = 'diesel_generator',
        inputs = {bus_diesel: solph.flows.Flow()},
        outputs= {
            bus_electricity: solph.flows.Flow(
                min=min_load,
                max=max_load,
            nominal_value=1200, variable_costs= 50,
            nonconvex = solph.NonConvex(),
            
            ),
            },
                coefficients=(c0, c1),
        )

Hi @DPapad,

first of all, welcome do the board! Unluckily, part-load-efficiencies will always introduce integer variables if efficiency increases with load. Using PiecewiseLinearConverter will even worsen the problem.

There are a few things you might try, though:

  1. You can reduce the MipGap so that the solver already stops close to the optimum.
  2. Make sure, you have a distinct optimum. Sometimes, there are a bazillion options that are equally good. The solver might try them all to find the optimum. (Esp., storage should have a loss rate.)
  3. You can use temporal aggregation or a rolling horizon approach to have fewer time steps in the optimization. (Even simple things like considering only every nth day can bring good results.)