Use of integer variables Juniper Error (MI-NLP)

Hi,
I’m trying to solve an optimization problem (MI-NLP) where I want certain variables to be integer values. I have tried to get a bunch of different packages/solver to work and landed on Juniper. My code works fine when I ran with only Ipopt, and didn’t use integer-restraints, but when trying to run with Juniper I get the error shown below the code.

using Pkg
using JuMP
using Ipopt
using Juniper
using HiGHS
using Dates
using CSV
using DataFrames



println("--- Start Program ---")

# GENERAL PARAMETERS
tfinal = 8759;
dt = 1;                     # (h) timestep
years=15;
efficiency_bat = 0.97;      
eta_charge = 0.95;          
eta_discharge = 0.95;       
SOC_bat_MAX = 1;            # (-) - Maximum SOC for batteries
SOC_bat_MIN = 0.35;         # (-) - Minimum SOC for batteries

# COST PARAMETERS
solar_capex = 668e3;                        # Capex Solar 
solar_opex = 14750*years;                   # Opex Solar
bat_capex = 630*1000;                       # Capex Battery
bat_opex = 7400*years;                      # Opex Battery
wave_capex = 5851275;                        # Capex OWC 
wave_opex = wave_capex*0.05 *years;           # Opex OWC
wind_capex = 1200e3;
wind_opex = 150000 * years; 
# DEMAND PARAMETERS
demand_t = CSV.read("Demand_data", DataFrame);

# GENERATION PARAMETERS
solar_available = CSV.read("Solar_data", DataFrame);
havkraft = CSV.read("Wave_data", DataFrame);
wind_ = CSV.read("Wind_data", DataFrame);

## INITIAL CONDITIONS
SOC_ini = 0.7;                     # (p.u) - Initial state of charge of the battery


#model

# Choose underlying solvers for Juniper
ipopt = optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)
highs = optimizer_with_attributes(HiGHS.Optimizer, "output_flag" => false)
m = Model(
    optimizer_with_attributes(
        Juniper.Optimizer,
        "nl_solver" => ipopt,
        "mip_solver" => highs,
    ),
)
Juniper.strong
#set_time_limit_sec(m, 800.0)

# Model
## VARIABLES
@variable(m, wind_generation_t[1:tfinal] >= 0)  # (MW) wind gen for each time step t
@variable(m, wind_capacity >= 0, Int)  # (MWh) wind capacity
@variable(m, wave_generation_t[1:tfinal] >= 0)  # (MW) wind gen for each time step t
@variable(m, wave_capacity >= 0, Int)  # (MWh) wind capacity
@variable(m, solar_generation_t[1:tfinal] >= 0, Int)  # (MW) solar gen for each time step t
@variable(m, solar_capacity >= 0)  # (MWh) solar capacity
@variable(m, battery_energy_capacity >= 0, Int)  # (MWh) battery capacity
@variable(m, battery_power_capacity >= 0)  # (MW) battery capacity
@variable(m, charge_battery_t[1:tfinal] >= 0)  # (MW) - Charge power for the battery
@variable(m, discharge_battery_t[1:tfinal] >= 0)  # (MW) - Discharge power for the battery
@variable(m, SOC_battery[1:tfinal] >= 0)  # (p.u) - State of charge of the battery 

# OBJECTIVE FUNCTION

@objective(m, Min, wave_capex + sum(wave_opex*wave_generation_t[1:tfinal]) + wind_capex + sum(wind_opex*wind_generation_t[1:tfinal]) + sum(solar_opex*solar_generation_t[1:tfinal]) + solar_capex + bat_opex*battery_energy_capacity + bat_capex);

# CONSTRAINT 0: WAVE GENERATION FOR ANY HOUR MUST BE LESS THAN MAX CAPACITY
for ti = 1:tfinal
    @NLconstraint(m, wave_generation_t[ti] <= wave_capacity);
end

# CONSTRAINT 1: WIND GENERATION FOR ANY HOUR MUST BE LESS THAN MAX CAPACITY
for ti = 1:tfinal
    @NLconstraint(m, wind_generation_t[ti] <= wind_capacity);
end

# CONSTRAINT 2: SOLAR GENERATION FOR ANY HOUR MUST BE LESS THAN MAX CAPACITY
for ti = 1:tfinal
    @NLconstraint(m, solar_generation_t[ti] <= solar_available[ti,1]);
end

# CONTRAINTS 3: BATTERY CHARGE FOR ANY HOUR MUST BE LESS THAN MAX
for ti = 1:tfinal
    @NLconstraint(m, charge_battery_t[ti] <= battery_power_capacity);
end

# COSTRAINT 4: BATTERY DISCHARGE FOR ANY HOUR MUST BE LESS THAN MAX
for ti = 1:tfinal
    @NLconstraint(m, discharge_battery_t[ti] <= battery_power_capacity);
end

# CONSTRAINT 5: DISCHARGE CAPACITY IS HALF THE BATTERY POWER CAPACITY
@NLconstraint(m, battery_power_capacity == 0.5*battery_energy_capacity);

# CONSTRAINTS 6: STATE OF CHARGE TRACKING
@NLconstraint(m, SOC_battery[1] == SOC_ini);

for ti = 2:tfinal
    @NLconstraint(m, SOC_battery[ti] == SOC_battery[ti-1] + (((eta_charge*charge_battery_t[ti])-(discharge_battery_t[ti]/eta_discharge))*dt)/battery_energy_capacity);
end

# CONSTRAINT 7: DEMAND BALANCING
for ti = 1:tfinal
    @NLconstraint(m, wave_capacity*wave_generation_t[ti] + wind_capacity*wind_generation_t[ti] + solar_capacity*solar_generation_t[ti] - charge_battery_t[ti] + discharge_battery_t[ti] == demand_t[ti,1]);
end

# CONSTRAINT 8a: SOC LIMITS (MAXIMUM)
for ti = 1:tfinal
    @NLconstraint(m, SOC_bat_MAX >= SOC_battery[ti]);
end

# CONSTRAINT 8b: SOC LIMITS (MINIMUM)
for ti = 1:tfinal
    @NLconstraint(m, SOC_battery[ti] >= SOC_bat_MIN);
end
    
## EXECUTION OF OPTIMIZATION PROBLEM

JuMP.optimize!(m)

When running the code after some time and getting the following outputs

nl_solver   : MathOptInterface.OptimizerWithAttributes(Ipopt.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("print_level") => 0])
mip_solver  : MathOptInterface.OptimizerWithAttributes(HiGHS.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("output_flag") => false])
log_levels  : [:Options, :Table, :Info]

#Variables: 52559
#IntBinVar: 8762
Obj Sense: Min

Start values are not feasible.
Status of relaxation: LOCALLY_SOLVED
Time for relaxation: 388.5899999141693
Relaxation Obj: 8.348895564000039e6

       MIPobj              NLPobj       Time
=============================================
┌ Warning: NLP couldn't be solved to optimality
└ @ Juniper C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\fpump.jl:405
         -                   -          60.8 

FP: 60.78700017929077 s
FP: 1 round
FP: No integral solution found

 ONodes   CLevel          Incumbent                   BestBound            Gap    Time   Restarts  GainGap
============================================================================================================
[ Info: Breaking out of strong branching as the time limit of 100.0 seconds got reached.
    1       2                 -                      8.34889556e6           -    102.3      1         -     
    2       3                 -                      8.45989529e6           -    121.7      -       86.7%   
    3       4                 -                      8.45989528e6           -    139.6      -       51.4%   
    4       5                 -                      8.45989528e6           -    157.3      -       78.5%   
    5       6                 -                      8.45989528e6           -    174.8      -       86.2%   
    6       7                 -                      8.45989528e6           -    192.9      -       79.3%
    7       8                 -                      8.45989528e6           -    209.9      -       90.3%
    8       9                 -                      8.45989528e6           -    227.0      -       91.2%
    9       10                -                      8.45989528e6           -    245.0      -       64.3%
   10       11                -                      8.45989528e6           -    262.3      -       96.7%
   11       12                -                      8.45989528e6           -    279.2      -       93.5%
   12       13                -                      8.45989528e6           -    297.7      -       74.7%   
   13       14                -                      8.45989528e6           -    314.5      -       98.7%   ^C

   14       15                -                      8.45989528e6           -    330.8      -       71.3%

The following error occurs. What am I doing wrong?

ERROR: InterruptException:
Stacktrace:
  [1] try_yieldto(undo::typeof(Base.ensure_rescheduled)) 
    @ Base .\task.jl:920
  [2] wait()
    @ Base .\task.jl:984
  [3] uv_write(s::Base.TTY, p::Ptr{UInt8}, n::UInt64)    
    @ Base .\stream.jl:1048
  [4] unsafe_write(s::Base.TTY, p::Ptr{UInt8}, n::UInt64)
    @ Base .\stream.jl:1120
  [5] write
    @ .\strings\io.jl:244 [inlined]
  [6] print(io::Base.TTY, s::String)
    @ Base .\strings\io.jl:246
  [7] print(::Base.TTY, ::String, ::String, ::Vararg{Any})
    @ Base .\strings\io.jl:46
  [8] println(::Base.TTY, ::String, ::Vararg{Any})        
    @ Base .\strings\io.jl:75
  [9] println(xs::String)
    @ Base .\coreio.jl:4
 [10] #print_table#49
    @ C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\table_log.jl:80 [inlined]
 [11] print_table
    @ C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\table_log.jl:60 [inlined]
 [12] solve_sequential(tree::Juniper.BnBTreeObj, last_table_arr::Vector{Any}, time_bnb_solve_start::Float64, fields::Vector{Symbol}, field_chars::Vector{Int64}, time_obj::Juniper.TimeObj)
    @ Juniper C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\BnBTree.jl:496
 [13] solvemip(tree::Juniper.BnBTreeObj)
    @ Juniper C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\BnBTree.jl:743
 [14] optimize!(model::Juniper.Optimizer)
    @ Juniper C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\MOI_wrapper\MOI_wrapper.jl:356
 [15] optimize!
    @ C:\Users\erlen\.julia\packages\MathOptInterface\wW7fs\src\Bridges\bridge_optimizer.jl:378 [inlined]
 [16] optimize!
    @ C:\Users\erlen\.julia\packages\MathOptInterface\wW7fs\src\MathOptInterface.jl:85 [inlined]
 [17] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Juniper.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
    @ MathOptInterface.Utilities C:\Users\erlen\.julia\packages\MathOptInterface\wW7fs\src\Utilities\cachingoptimizer.jl:316
 [18] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ JuMP C:\Users\erlen\.julia\packages\JuMP\D44Aq\src\optimizer_interface.jl:448
 [19] optimize!(model::Model)
    @ JuMP C:\Users\erlen\.julia\packages\JuMP\D44Aq\src\optimizer_interface.jl:409
 [20] top-level scope
    @ c:\Users\erlen\OneDrive\Bilder\Dokumenter\UPC\EnergyStorage\Project\masterOpt.jl:131

Hi @Erlendgh, welcome to the forum.

That’s a weird error. How did you run the code? It looks like something interrupted the printing?

I assume not, but did you accidentally press CTRL+C? That would have the same error.

1 Like

Hi, thanks!
Maybe I did, not really sure what caused the problem, but it doesn’t occur anymore.

I found another error in my code which caused the problem to be unsolvable (Integer restriction on the solar generation in each hour instead of the capacity). Atleast my code works now.

Thanks!

1 Like