Constraint to return variable equal to zero

282 views
Skip to first unread message

Thomas Frei

unread,
May 11, 2015, 4:41:23 PM5/11/15
to pyomo...@googlegroups.com
Hi
I'm trying to use a constraint to assign a value of 0 to a variable (m.PW_SS_exp_i) for some points where a condition is not fullfilled. Unfortunately, this doesn't seem to work as I was hoping. The values I get are close to 0, but not exactly 0. I'm using IPOPT, but also have Couenne installed, if that would help somehow. Does someone know how to do that? 

Thanks for your help

def SS_entry_exp_def(m, ss, t):
if value(m.p[m.n_inc[ss],t])**2>=value(m.p_ss[ss,t])**2: #Expander
return m.PW_SS_exp_i[ss, t]==((m.z_gas*m.R_id*m.T_avg*(m.gamma/(m.gamma-1)))/m.M_molar*10**3*m.m_in_ss[ss,t])/m.eta_c*10**-6*((m.p_ss[ss,t]**2/m.p[m.n_inc[ss],t]**2)**(m.gamma/(m.gamma-1))-1)/m.t_period
else:
return m.PW_SS_exp_i[ss,t]==0
m.SS_entry_exp_con=Constraint(m.ss, m.t, rule=SS_entry_exp_def, doc="Storage entry expander power [MW]")

Carl Laird

unread,
May 11, 2015, 9:41:50 PM5/11/15
to pyomo...@googlegroups.com
Hi Thomas,

Ipopt converges the equality constraints to within a specified tolerance (1e-8 by default). How far away are your variables from zero at the solution? Is it within a tolerance such as this?

Nevertheless, if you want the variable to be exactly zero, then I would recommend adding a BuildAction and actually fixing the variables to zero in the build action prior to any solve.

Regards,

Carl D. Laird
Associate Professor, School of Chemical Engineering, Purdue University
Ph: 765.494.0085



--
You received this message because you are subscribed to the Google Groups "Pyomo Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyomo-forum...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Thomas Frei

unread,
May 12, 2015, 3:19:34 AM5/12/15
to pyomo...@googlegroups.com
Hi Carl,

Thank you for your answer. A tolerance of 1e-8 would be enough, but after 50'000 iterations the variables are still in the range of 1e-5 and therefore the optimization doesn't stop. I guess its possible to change this tolerance? 

Thomas Frei

unread,
May 12, 2015, 8:05:07 AM5/12/15
to pyomo...@googlegroups.com
Update: I changed the tolerance with mu_init, but now I get a message: "Slacks too small, adjusting variable bounds" and "converged to a point of local infeasibility" ....

Carl Laird

unread,
May 12, 2015, 8:19:23 AM5/12/15
to pyomo...@googlegroups.com
Hi Thomas,

The parameter mu_init does not adjust the tolerance for the constraints. It changes the initial value of the barrier parameter. This barrier parameter starts out reasonably large (default: 0.1), and it is gradually reduced as the problem is solved. The value of the barrier parameter, in essence, determines how close a variable can be to its bound at the solution. If the barrier parameter is small, the variable can move close to its bound, however, the subproblem is harder to solve (more curvature from the barrier term). 

I have one question and one comment:

1) For the variables you are trying to fix to zero, do you also have a bound? I.e. do you have x >= 0 and x = 0. This may cause problems with Ipopt. Since it is a barrier method, the x >= 0 constraint is not typically satisfied exactly at the solution, but is usually more like x >= eps. If this is the case, you may want to remove the lower bound for the variables you are trying to fix to zero.

2) I still suggest that you use a build action to fix the variables to zero instead of using a constraint. I believe that this does exactly what you want without any of the numerical difficulties. Your code from below would look something like the following (not tested since I don’t have the full model).

def SS_entry_exp_def(m, ss, t):
    if value(m.p[m.n_inc[ss],t])**2>=value(m.p_ss[ss,t])**2: #Expander
        return m.PW_SS_exp_i[ss, t]==((m.z_gas*m.R_id*m.T_avg*(m.gamma/(m.gamma-1)))/m.M_molar*10**3*m.m_in_ss[ss,t])/m.eta_c*10**-6*((m.p_ss[ss,t]**2/m.p[m.n_inc[ss],t]**2)**(m.gamma/(m.gamma-1))-1)/m.t_period
    else:
return Constraint.Skip
m.SS_entry_exp_con=Constraint(m.ss, m.t, rule=SS_entry_exp_def, doc="Storage entry expander power [MW]”)

def SS_entry_exp_def_BA(m):
    for ss in m.ss:
        for t in m.t:
            if value(m.p[m.n_inc[ss],t])**2 < value(m.p_ss[ss,t])**2: # not the chance in inequality
                m.PW_SS_exp_i[ss,t] = 0
                m.PW_SS_exp_i[ss,t].fixed = 0
m.SS_entry_exp_con_BA=BuildAction(rule=SS_entry_exp_def_BA)


Regards,

Carl D. Laird
Associate Professor, School of Chemical Engineering, Purdue University
Ph: 765.494.0085



Thomas Frei

unread,
May 12, 2015, 8:54:44 AM5/12/15
to pyomo...@googlegroups.com
Thank you very much - this works perfectly!
Reply all
Reply to author
Forward
0 new messages