Pyomo dae with discrete set of inputs for objective function

52 views Asked by At

I am new to Python and Pyomo, and including this code used for sizing a capacitor based on a simple differential equation. The reference is a discrete array which is interpolated to be used in in the problem formulation. For validating my results I am using this line but it gives an error.

Pref = [pyo.value(m.intPload[i]) for i in m.t]

Error: ValueError: Error evaluating Param value (intPload[0.03569]): The Param value is currently set to an invalid value. This is typically from a scalar Param or mutable Indexed Param without an initial or default value.

**Entire code:

import numpy as np
from scipy import integrate
import math
import matplotlib.pyplot as plt
import pyomo.environ as pyo
from pyomo.dae import ContinuousSet, DerivativeVar
model = m = pyo.ConcreteModel()


# power and time data
t1 = np.array([0, 1, 2, 3, 4, 5]) #s
P1 = np.array([0, 10, 20, 30, 40, 0]) # W
# resample the data
dt      = 1 # delta time, resampled every one second
tFinal  = math.floor(t1[t1.size-1])
numSims = math.ceil(tFinal/dt)
tsecs   = np.linspace(0, tFinal, numSims)
Pload   = np.interp(tsecs, t1, P1)
# Capacitor rating
Cc      = 1
Rsc     = 2.4e-3 # capacitor internal resistance
VcMax   = 3 # maximum capacitor cell voltage
IcMax   = 50

# Pyomo problem formulation
m.t     =  ContinuousSet(initialize=tsecs)
m.Vc    = pyo.Var(m.t, bounds =(0.5*VcMax, VcMax))
m.VcT   = pyo.Var(m.t, bounds =(0.5*VcMax, VcMax))
m.Ic    = pyo.Var(m.t, bounds=(-IcMax, IcMax))
m.N_sc  = pyo.Var(bounds=(0, 100))
m.N_pc  = pyo.Var(bounds=(0, 100))
m.dVcdt = DerivativeVar(m.Vc, wrt=m.t)
m.intPload = pyo.Param(m.t, mutable=True)

timepoints  = list(m.t)
Pload_Int   = np.interp(timepoints, t1, P1)
for i,t in enumerate(timepoints):
     m.intPload[t] = Pload_Int[i]

m.obj = pyo.Objective(expr=(m.N_sc+m.N_pc)**2 + sum( (m.VcT[i]*m.N_sc*m.Ic[i]*m.N_pc - m.intPload[i])**2 for i in m.t), sense=pyo.minimize)

def _Vcdot(m, t):
    return m.dVcdt[t] == -m.Ic[t]/Cc
m.Vcdot = pyo.Constraint(m.t,rule=_Vcdot)

def _VcTR(m, t):
    return m.VcT[t] == m.Vc[t] -m.Ic[t]*Rsc
m.VcTR = pyo.Constraint(m.t,rule=_VcTR)

def _init_conditions(m):
    yield m.Vc[0] == VcMax
    #yield m.VcT[0] == VcMax
m.init_conditions = pyo.ConstraintList(rule=_init_conditions)

# Discretize model using Orthogonal Collocation
discretizer = pyo.TransformationFactory('dae.collocation')
discretizer.apply_to(model, nfe=8, ncp=5)


solver=pyo.SolverFactory('ipopt')
results = solver.solve(model,tee=True)


x1 = [pyo.value(m.Ic[i]) for i in m.t]
Pl = [pyo.value(m.Ic[i]*m.VcT[i]*m.N_sc*m.N_pc) for i in m.t]
Pref = [pyo.value(m.intPload[i]) for i in m.t]

#Pl2 = [pyo.value(m.intPload[i]) for i in m.t]


diffPl = [pyo.value(m.Ic[i]*m.VcT[i]*m.N_sc*m.N_pc - m.intPload[i]) for i in m.t]


plt.plot(x1)
plt.show( )

Error message: ValueError: Error evaluating Param value (intPload[0.03569]): The Param value is currently set to an invalid value. This is typically from a scalar Param or mutable Indexed Param without an initial or default value.

With the Pyomo DAE where a continuous set initialized at tsecs is used: How can I assign a constant value to a variable over certain portion of m.t? See attached picture: I am intending the values of m.intPload[i] to have steps (ladder type) in it but with the above code rather ending in sampling instances. All in all, I am trying to discretize the design space over which the code is executing or trying for atleast some of the variables to have a discrete set of values enter image description here

1

There are 1 answers

1
Bethany Nicholson On

You need to move the lines interpolating values for intPload to after you have called the discretization transformation. The discretization transformation is adding time points to m.t which your interpolation code is missing.