Reputation: 61289
I am using PyOmo to generate a nonlinear model which will ultimately be solved with Ipopt. The model is as follows:
from pyomo.environ import *
from pyomo.dae import *
m = ConcreteModel()
m.t = ContinuousSet(bounds=(0,100))
m.T = Param(default=100,mutable=True)
m.a = Param(default=0.1)
m.kP = Param(default=20)
m.P = Var(m.t, bounds=(0,None))
m.S = Var(m.t, bounds=(0,None))
m.u = Var(m.t, bounds=(0,1), initialize=0.5)
m.Pdot = DerivativeVar(m.P)
m.Sdot = DerivativeVar(m.S)
m.obj = Objective(expr=m.S[100],sense=maximize)
def _Pdot(M,i):
if i == 0:
return Constraint.Skip
return M.Pdot[i] == (1-M.u[i])*(M.P[i]**0.75)
def _Sdot(M,i):
if i == 0:
return Constraint.Skip
return M.Sdot[i] == M.u[i]*0.2*(M.P[i]**0.75)
def _init(M):
yield M.P[0] == 2
yield M.S[0] == 0
yield ConstraintList.End
m.Pdotcon = Constraint(m.t, rule=_Pdot)
m.Sdotcon = Constraint(m.t, rule=_Sdot)
m.init_conditions = ConstraintList(rule=_init)
discretizer = TransformationFactory('dae.collocation')
discretizer.apply_to(m,nfe=100,ncp=3,scheme='LAGRANGE-RADAU')
discretizer.reduce_collocation_points(m,var=m.u,ncp=1,contset=m.t)
solver = SolverFactory('ipopt')
results = solver.solve(m,tee=False)
Running the model results in the following error:
Error evaluating constraint 1: can't evaluate pow'(0,0.75).
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/dist-packages/pyomo/opt/base/solvers.py", line 577, in solve
"Solver (%s) did not exit normally" % self.name)
pyutilib.common._exceptions.ApplicationError: Solver (asl) did not exit normally
The first part of the error comes from Ipopt whereas the second part comes from PyOmo. Evidently the issue has something ot do with the term M.P[i]**0.75
in the constraints, but changing the power does not resolve the issue (though 2.0
did work).
How can I resolve this?
Upvotes: 3
Views: 1525
Reputation: 101
I would add to Richard's answer:
you might also need to update the initial value of your variable as ipopt assumes 0 if not specified, so it will evaluate the variable at 0 for the first iteration.
hence:
m.P = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
m.S = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
instead of 1e-20 as initialize you might use a value more relevant to your problem
Upvotes: 3
Reputation: 61289
The error message states that pow'(0,0.75)
cannot be evaluated. The '
character in this function indicates the first derivative (''
would indiate the second derivative). The message is effectively saying that the first derivative does not exist or results in an infinity at zero.
Resolving the issue is easy: bound your variables to a non-zero value as follows:
m.P = Var(m.t, bounds=(1e-20,None))
m.S = Var(m.t, bounds=(1e-20,None))
Upvotes: 3