Closed fahim831 closed 1 month ago
Hi @fahim831, I was able to reproduce your issue with the following modification of your example:
# example.py
from pyomo.environ import *
from pyomo.dae import *
model = ConcreteModel()
model.t = ContinuousSet(bounds=(0, 5))
model.x = ContinuousSet(bounds=(0, 3))
model.y = Var(model.t, model.x)
model.z = Var(model.t, model.x)
model.dydt = DerivativeVar(model.y, wrt=model.t)
model.dzdt = DerivativeVar(model.z, wrt=model.t)
model.dydx = DerivativeVar(model.y, wrt=model.x)
model.dzdx = DerivativeVar(model.z, wrt=model.x)
# 2 differential equations here in y and z
# 2 algebraic equations here in y and z
#
# Discretize both y and z
@model.Constraint(model.t, model.x)
def diffeq1(m, t, x):
return m.dydt[t, x] == m.z[t, x] - m.y[t, x]
model.obj = Objective(
expr=sum(model.y[t, x]**2 + model.z[t, x]**2 for t in model.t for x in model.x),
sense=minimize,
)
TransformationFactory("dae.finite_difference").apply_to(model, wrt=model.t, nfe=10, scheme="BACKWARD")
TransformationFactory("dae.finite_difference").apply_to(model, wrt=model.x, nfe=10, scheme="BACKWARD")
# create the scaling factors
model.scaling_factor = Suffix(direction=Suffix.EXPORT)
model.scaling_factor[model.diffeq1] = 10 # scale diffeq1
model.scaling_factor[model.z] = 0.1 # scale z
# transform the model
scaled_model = TransformationFactory('core.scale_model').create_using(model)
solver = SolverFactory('ipopt')
results = solver.solve(scaled_model, tee=True)
model = TransformationFactory('core.scale_model').propagate_solution(scaled_model, model)
This is because the derivative variables at (0,0) are (a) not initialized and (b) not used in the model (with backwards difference, anyway). A workaround is to initialize the derivative variables, e.g. model.dydt = DerivativeVar(model.y, wrt=model.t, initialize=0)
, but we should probably handle this in propagate_solution
anyway. I'll look into it and see if this is a quick fix.
Hi @Robbybp, thanks. I was able to make it run after initializing all the derivatives at 0. Although, after it runs and finds a solution, when I call model.y
, I get this new error (probably unrelated to the propagate_solution
definition, however):
AttributeError: 'NoneType' object has no attribute 'y'
I am guessing the solver is outputting a false positive for the optimal solution being found? Because when I check the results from solver.solve,
I get this:
Solution:
- number of solutions: 0
number of solutions displayed: 0
From a quick glance, this is probably because propagate_solution
returns None
, and we are resetting model
to this return value. Just changing the last line to
TransformationFactory('core.scale_model').propagate_solution(scaled_model, model)
should fix that.
Thanks! That was the issue.
https://github.com/Pyomo/pyomo/issues/2817 appears to be related.
Summary
I am trying to scale, solve, and unscale a pyomo model. The code itself worked well until I tried to scale but it didn't get a solution probably due to scaling issues. Now, after scaling, the model solves but I get an error when I try to scale it back. Unfortunately, I couldn't find any application in the doc on how to actually use the ```propagate_solution''' method.
I will try to provide a few lines of code to summarize what I'm doing without making it extensively long. The last line is what gives me the error
Steps to reproduce the issue
Error Message
Information on your system
Pyomo version: 6.7.1 Python version: 3.12 Operating system: Mac OS Sonoma How Pyomo was installed (PyPI, conda, source): conda Solver (if applicable): ipopt