Thanks for the quick reply @joaquimg.
I’m setting starts at different times, but this should not be an issue.
Since primal infeasibility is usually significant (>1e+1), it should not be related to tolerances.
However, I believe I was able to find the reason for the primal infeasibility.
For some reason, it seems that the lower level dual variables equal to 0 are not correctly set in Ipopt.
Similar to the code above, I was able to query the set starting values (using dual_start_value() and start_value() ) of a toy model. The starting values look as follows:
==, eq_mass_bal[DEU,DEU,L,2015]: 85102.54945586761
==, eq_stor_cycle[(:DEU, :DEU, :SEAS, :L, 2015)]: 472.12310036263966
>=, NNG_D_A[GALB_ITA,2015]: 6522.12
>=, NNG_D_X[DEU,SEAS,2015]: 5000.0
>=, NNG_D_W[DEU,SEAS,2015]: 150.0
>=, NNG_Q_P[(:DEU, :DEU, :R1, :L, 2015)]: 0.0
>=, NNG_Q_S[(:DEU, :DEU, :L, 2015)]: 0.0
>=, NNG_F_A[(:DEU, :GALB_ITA, :L, 2015)]: 4.158
>=, NNG_F_I[(:DEU, :DEU, :SEAS, :L, 2015)]: 0.0
>=, NNG_F_X[(:DEU, :DEU, :SEAS, :L, 2015)]: 1325.9779104954403
<=, eq_cap_a[GALB_ITA,L,2015]: -0.0
<=, eq_cap_p[(:DEU, :DEU, :R1, :L, 2015)]: -75586.5451727892
<=, eq_cap_x[DEU,SEAS,L,2015]: -0.0
<=, eq_cap_w[DEU,SEAS,2015]: -0.0
<=, eq_lim_a[GALB_ITA,2015]: -0.0
<=, eq_lim_x[DEU,SEAS,2015]: -0.0
<=, eq_lim_w[DEU,SEAS,2015]: -0.0
var, Q_S[(:DEU, :DEU, :L, 2015)]: 16.84987
var, Q_P[(:DEU, :DEU, :R1, :L, 2015)]: 16.84987
var, F_A[(:DEU, :GALB_ITA, :L, 2015)]: 0.0
var, F_I[(:DEU, :DEU, :SEAS, :L, 2015)]: 8.71186666981928e-14
var, D_X[DEU,SEAS,2015]: 0.0
var, calib_int[(:DEU, :L, 2015)]: 1.0
var, F_X[(:DEU, :DEU, :SEAS, :L, 2015)]: 8.581188669771992e-14
var, D_W[DEU,SEAS,2015]: 0.0
var, D_A[GALB_ITA,2015]: 0.0
, where ==,>=,<= indicates duals to (in-)equalities, and var indicates a lower level primal variable.
However, when taking a look at the initial points of iteration 0 in IPOPT, this looks as follows:
DenseVector "curr_x" with 26 elements:
curr_x[ 1]= 6.5221199999999999e+03 g
curr_x[ 2]= 5.0000000000000000e+03 g
curr_x[ 3]= 1.5000000000000000e+02 g
curr_x[ 4]= 9.9999900000000003e-03 (g)
curr_x[ 5]= 9.9999900000000003e-03 (g)
curr_x[ 6]= 4.1580000000000004e+00 g
curr_x[ 7]= 9.9999900000000003e-03 (g)
curr_x[ 8]= 1.3259779104954403e+03 g
curr_x[ 9]=-9.9999900000000003e-03 (l)
curr_x[ 10]=-7.5586545172789207e+04 l
curr_x[ 11]=-9.9999900000000003e-03 (l)
curr_x[ 12]=-9.9999900000000003e-03 (l)
curr_x[ 13]=-9.9999900000000003e-03 (l)
curr_x[ 14]=-9.9999900000000003e-03 (l)
curr_x[ 15]=-9.9999900000000003e-03 (l)
curr_x[ 16]= 0.0000000000000000e+00 v
curr_x[ 17]= 0.0000000000000000e+00 v
curr_x[ 18]= 0.0000000000000000e+00 v
curr_x[ 19]= 1.6849869999999999e+01 v
curr_x[ 20]= 1.6849869999999999e+01 v
curr_x[ 21]= 0.0000000000000000e+00 v
curr_x[ 22]= 8.7118666698192804e-14 v
curr_x[ 23]= 8.5811886697719921e-14 v
curr_x[ 24]= 1.0000000000000000e+00 v
curr_x[ 25]= 8.5102549455867615e+04 e
curr_x[ 26]= 4.7212310036263966e+02 e
, where v,e,l,g are edited and indicate my guess for a corresponding primal variable, or a lower level dual to equalities (e) or lesser/greater inequalites (l,g).
It seems that primals and duals not equal zero are set correctly. Duals equal to zero are not set correctly, they are set to +/- 9.9999900000000003e-03.
This behavior even persists when not explicitly setting lower dual start values to zero (for example by only iterating set_dual_start_value() over nonzero duals).
I guess, setting dual starts to zero does not really set them to zero and the default behavior also does not do this?
If so, does anyone know the recommended way to set the dual start to zero if desired?
Edit: The problem was in my Ipopt settings. While I did use the Ipopt options as indicated here: https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.589.5002&rep=rep1&type=pdf (p.672-673), I forgot to set “warm_start_init_point” to “yes”. The solution was rather simple in the end…
PS: I am interested in taking a shot at the iterative product mode, but not sure if I can get it running in reasonable time. I will open an issue in the next few days and take a look at it ![]()