The Pyomo optimization modeling framework for formulating, analyzing, and solving mathematical optimization problems
—
Components for modeling dynamic systems with differential and algebraic equations. DAE capabilities enable optimization of systems with time-dependent behavior, continuous processes, and dynamic constraints.
Components for defining continuous domains and time discretization in dynamic optimization problems.
class ContinuousSet:
"""
Continuous set component for DAE modeling.
Represents a continuous domain (typically time) that can be
discretized for numerical solution of differential equations.
"""
def __init__(self, *args, **kwargs): ...
def get_finite_elements(self):
"""
Get finite element discretization points.
Returns:
list: Discretization points
"""
def get_discretization_info(self):
"""
Get discretization scheme information.
Returns:
dict: Discretization metadata
"""Components for defining derivative variables and their relationships to state variables.
class DerivativeVar:
"""
Derivative variable component for differential equations.
Represents the derivative of a state variable with respect
to a continuous set (typically time).
"""
def __init__(self, *args, **kwargs): ...
def get_state_var(self):
"""
Get the state variable this derivative represents.
Returns:
Var: Associated state variable
"""
def get_continuousset(self):
"""
Get the continuous set for differentiation.
Returns:
ContinuousSet: Continuous domain
"""Components for defining integral expressions and constraints in dynamic systems.
class Integral:
"""
Integral component for dynamic optimization.
Represents integral expressions over continuous domains,
commonly used in objective functions and constraints.
"""
def __init__(self, *args, **kwargs): ...
def get_integrand(self):
"""
Get the integrand expression.
Returns:
Expression: Function being integrated
"""
def get_continuousset(self):
"""
Get the integration domain.
Returns:
ContinuousSet: Domain of integration
"""Interface for simulating DAE systems and initializing optimization models.
class Simulator:
"""
DAE simulation interface for model initialization and analysis.
Provides capabilities for simulating differential-algebraic
equation systems to generate initial conditions and validate models.
"""
def __init__(self, model, **kwargs): ...
def simulate(self, numpoints=None, integrator=None):
"""
Simulate the DAE system.
Args:
numpoints (int, optional): Number of simulation points
integrator (str, optional): Integration method
Returns:
dict: Simulation results
"""
def initialize_model(self):
"""
Initialize model with simulation results.
"""
def get_profile(self, variable):
"""
Get variable profile from simulation.
Args:
variable: Variable to extract profile for
Returns:
dict: Time-indexed variable values
"""Exception class for DAE-specific errors and modeling issues.
class DAE_Error(Exception):
"""DAE-specific error class for differential equation modeling issues."""
def __init__(self, message): ...from pyomo.environ import *
from pyomo.dae import ContinuousSet, DerivativeVar
model = ConcreteModel()
# Define time domain
model.time = ContinuousSet(bounds=(0, 10))
# State variables
model.x1 = Var(model.time, bounds=(0, None)) # Concentration A
model.x2 = Var(model.time, bounds=(0, None)) # Concentration B
# Derivative variables
model.dx1dt = DerivativeVar(model.x1, wrt=model.time)
model.dx2dt = DerivativeVar(model.x2, wrt=model.time)
# Parameters
model.k1 = Param(initialize=2.5) # Reaction rate constant 1
model.k2 = Param(initialize=1.0) # Reaction rate constant 2
# Initial conditions
model.x1[0].fix(1.0) # Initial concentration A
model.x2[0].fix(0.0) # Initial concentration B
# Differential equations: A -> B -> C
def ode1_rule(model, t):
return model.dx1dt[t] == -model.k1 * model.x1[t]
def ode2_rule(model, t):
return model.dx2dt[t] == model.k1 * model.x1[t] - model.k2 * model.x2[t]
model.ode1 = Constraint(model.time, rule=ode1_rule)
model.ode2 = Constraint(model.time, rule=ode2_rule)
# Apply discretization
discretizer = TransformationFactory('dae.finite_difference')
discretizer.apply_to(model, nfe=20, wrt=model.time)from pyomo.environ import *
from pyomo.dae import ContinuousSet, DerivativeVar, Integral
model = ConcreteModel()
# Time domain
model.time = ContinuousSet(bounds=(0, 1))
# State variables
model.x1 = Var(model.time, bounds=(-10, 10)) # Position
model.x2 = Var(model.time, bounds=(-10, 10)) # Velocity
# Control variable
model.u = Var(model.time, bounds=(-1, 1)) # Control input
# Derivatives
model.dx1dt = DerivativeVar(model.x1, wrt=model.time)
model.dx2dt = DerivativeVar(model.x2, wrt=model.time)
# Initial conditions
model.x1[0].fix(0) # Start at origin
model.x2[0].fix(0) # Start at rest
# Terminal conditions
model.x1[1].fix(1) # End at position 1
model.x2[1].fix(0) # End at rest
# System dynamics
def position_ode(model, t):
return model.dx1dt[t] == model.x2[t]
def velocity_ode(model, t):
return model.dx2dt[t] == model.u[t]
model.position_ode = Constraint(model.time, rule=position_ode)
model.velocity_ode = Constraint(model.time, rule=velocity_ode)
# Objective: minimize control effort
model.obj_integrand = Var(model.time)
model.integrand_def = Constraint(
model.time,
rule=lambda model, t: model.obj_integrand[t] == model.u[t]**2
)
model.objective_integral = Integral(
model.time,
wrt=model.time,
rule=lambda model, t: model.obj_integrand[t]
)
model.obj = Objective(expr=model.objective_integral, sense=minimize)
# Apply discretization
discretizer = TransformationFactory('dae.collocation')
discretizer.apply_to(model, nfe=10, ncp=3, wrt=model.time)from pyomo.environ import *
from pyomo.dae import ContinuousSet, DerivativeVar, Integral
model = ConcreteModel()
# Time domain for batch process
model.time = ContinuousSet(bounds=(0, 2)) # 2 hours
# State variables
model.CA = Var(model.time, bounds=(0, 10)) # Concentration of A
model.CB = Var(model.time, bounds=(0, 10)) # Concentration of B
model.CC = Var(model.time, bounds=(0, 10)) # Concentration of C
model.T = Var(model.time, bounds=(300, 400)) # Temperature
# Control variable
model.Q = Var(model.time, bounds=(-50, 50)) # Heat input
# Derivatives
model.dCAdt = DerivativeVar(model.CA, wrt=model.time)
model.dCBdt = DerivativeVar(model.CB, wrt=model.time)
model.dCCdt = DerivativeVar(model.CC, wrt=model.time)
model.dTdt = DerivativeVar(model.T, wrt=model.time)
# Initial conditions
model.CA[0].fix(2.0) # Initial concentration A
model.CB[0].fix(0.0) # Initial concentration B
model.CC[0].fix(0.0) # Initial concentration C
model.T[0].fix(350) # Initial temperature
# Parameters
model.k0 = Param(initialize=1e6) # Pre-exponential factor
model.E = Param(initialize=8000) # Activation energy
model.R = Param(initialize=8.314) # Gas constant
model.rho = Param(initialize=1000) # Density
model.Cp = Param(initialize=1.0) # Heat capacity
# Reaction rate expressions
def k_expr(model, t):
return model.k0 * exp(-model.E / (model.R * model.T[t]))
def reaction_rate(model, t):
return k_expr(model, t) * model.CA[t]
# Mass balance ODEs: A -> B -> C
def mass_balance_A(model, t):
return model.dCAdt[t] == -reaction_rate(model, t)
def mass_balance_B(model, t):
return model.dCBdt[t] == reaction_rate(model, t) - 0.5 * reaction_rate(model, t)
def mass_balance_C(model, t):
return model.dCCdt[t] == 0.5 * reaction_rate(model, t)
# Energy balance
def energy_balance(model, t):
return model.rho * model.Cp * model.dTdt[t] == \
-10000 * reaction_rate(model, t) + model.Q[t]
model.mass_A = Constraint(model.time, rule=mass_balance_A)
model.mass_B = Constraint(model.time, rule=mass_balance_B)
model.mass_C = Constraint(model.time, rule=mass_balance_C)
model.energy = Constraint(model.time, rule=energy_balance)
# Objective: maximize final concentration of B
model.obj = Objective(expr=model.CB[2], sense=maximize)
# Apply discretization
discretizer = TransformationFactory('dae.finite_difference')
discretizer.apply_to(model, nfe=40, wrt=model.time, scheme='BACKWARD')from pyomo.environ import *
from pyomo.dae import ContinuousSet, DerivativeVar, Simulator
# Create DAE model
model = ConcreteModel()
model.time = ContinuousSet(bounds=(0, 5))
model.x = Var(model.time)
model.dxdt = DerivativeVar(model.x, wrt=model.time)
# Model equations
model.x[0].fix(1.0)
model.ode = Constraint(
model.time,
rule=lambda m, t: m.dxdt[t] == -0.5 * m.x[t]
)
# Simulate the model
sim = Simulator(model, package='scipy')
tsim, profiles = sim.simulate(numpoints=100, integrator='odeint')
# Use simulation results to initialize discretized model
discretizer = TransformationFactory('dae.finite_difference')
discretizer.apply_to(model, nfe=20, wrt=model.time)
# Initialize with simulation profiles
for t in model.time:
if t in profiles:
model.x[t].set_value(profiles[t]['x'])
# Now solve optimization problem
solver = SolverFactory('ipopt')
results = solver.solve(model)from pyomo.environ import *
from pyomo.dae import ContinuousSet, DerivativeVar, Integral
model = ConcreteModel()
model.time = ContinuousSet(bounds=(0, 1))
# Variables
model.x = Var(model.time, bounds=(0, None))
model.u = Var(model.time, bounds=(-2, 2))
model.dxdt = DerivativeVar(model.x, wrt=model.time)
# Initial condition
model.x[0].fix(0)
# Dynamics
model.ode = Constraint(
model.time,
rule=lambda m, t: m.dxdt[t] == m.u[t]
)
# Integral constraint: average control must be zero
model.avg_control = Integral(
model.time,
wrt=model.time,
rule=lambda m, t: m.u[t]
)
model.avg_constraint = Constraint(expr=model.avg_control == 0)
# Integral objective: minimize integral of x^2
model.performance = Integral(
model.time,
wrt=model.time,
rule=lambda m, t: m.x[t]**2
)
model.obj = Objective(expr=model.performance, sense=minimize)
# Apply discretization
discretizer = TransformationFactory('dae.collocation')
discretizer.apply_to(model, nfe=20, ncp=2, wrt=model.time)Install with Tessl CLI
npx tessl i tessl/pypi-pyomo