def _populate_block_with_vars_expressions(self, b): b.x = pyo.Var() b.X1 = pyo.Var([1]) b.X2 = pyo.Var([1]) b.e = pyo.Expression() b.E1 = pyo.Expression([1]) b.E2 = pyo.Expression([1])
def build(self): self.x = pyo.Var(initialize=0) self.pressure = pyo.Var() self.enth_mol = pyo.Var() self.temperature = pyo.Expression(expr=self.enth_mol*2.0) self.div0 = pyo.Expression(expr=4.0/self.x) self.flow_mol = pyo.Var()
def cost_membrane(blk, membrane_cost, factor_membrane_replacement): """ Generic function for costing a membrane. Assumes the unit_model has an `area` variable or parameter. Args: membrane_cost - The cost of the membrane in currency per area factor_membrane_replacement - Membrane replacement factor [fraction of membrane replaced/year] """ _make_capital_cost_var(blk) _make_fixed_operating_cost_var(blk) blk.membrane_cost = pyo.Expression(expr=membrane_cost) blk.factor_membrane_replacement = pyo.Expression( expr=factor_membrane_replacement) blk.capital_cost_constraint = pyo.Constraint( expr=blk.capital_cost == blk.membrane_cost * pyo.units.convert(blk.unit_model.area, pyo.units.m**2)) blk.fixed_operating_cost_constraint = pyo.Constraint( expr=blk.fixed_operating_cost == blk.factor_membrane_replacement * blk.membrane_cost * pyo.units.convert(blk.unit_model.area, pyo.units.m**2))
def _create_parmest_model(self, data): """ Modify the Pyomo model for parameter estimation """ from pyomo.core import Objective model = self.model_function(data) for theta in self.theta_names: try: var_validate = eval('model.'+theta) var_validate.fixed = False except: print(theta +'is not a variable') if self.obj_function: for obj in model.component_objects(Objective): obj.deactivate() def FirstStageCost_rule(model): return 0 model.FirstStageCost = pyo.Expression(rule=FirstStageCost_rule) model.SecondStageCost = pyo.Expression(rule=_SecondStateCostExpr(self.obj_function, data)) def TotalCost_rule(model): return model.FirstStageCost + model.SecondStageCost model.Total_Cost_Objective = pyo.Objective(rule=TotalCost_rule, sense=pyo.minimize) self.parmest_model = model return model
def declare_expr_shunt_power_at_bus(model, index_set, shunt_attrs, coordinate_type=CoordinateType.POLAR): """ Create the expression for the shunt power at the bus """ m = model expr_set = decl.declare_set('_expr_shunt_at_bus_set', model, index_set) m.shunt_p = pe.Expression(expr_set, initialize=0.0) m.shunt_q = pe.Expression(expr_set, initialize=0.0) if coordinate_type == CoordinateType.POLAR: for bus_name in expr_set: if bus_name in shunt_attrs['bus']: vmsq = m.vm[bus_name]**2 m.shunt_p[bus_name] = shunt_attrs['gs'][bus_name] * vmsq m.shunt_q[bus_name] = -shunt_attrs['bs'][bus_name] * vmsq elif coordinate_type == CoordinateType.RECTANGULAR: for bus_name in expr_set: if bus_name in shunt_attrs['bus']: vmsq = m.vr[bus_name]**2 + m.vj[bus_name]**2 m.shunt_p[bus_name] = shunt_attrs['gs'][bus_name] * vmsq m.shunt_q[bus_name] = -shunt_attrs['bs'][bus_name] * vmsq
def declare_expression_pgqg_operating_cost(model, index_set, p_costs, q_costs=None): """ Create the Expression objects to represent the operating costs for the real and reactive (if present) power of each of the generators. """ m = model expr_set = decl.declare_set('_expr_g_operating_cost', model=model, index_set=index_set) m.pg_operating_cost = pe.Expression(expr_set) m.qg_operating_cost = pe.Expression(expr_set) found_q_costs = False for gen_name in expr_set: if p_costs is not None and gen_name in p_costs: #TODO: We assume that the costs are polynomial type assert p_costs[gen_name]['cost_curve_type'] == 'polynomial' m.pg_operating_cost[gen_name] = \ sum(v*m.pg[gen_name]**i for i, v in p_costs[gen_name]['values'].items()) if q_costs is not None and gen_name in q_costs: #TODO: We assume that the costs are polynomial type assert q_costs['cost_curve_type'] == 'polynomial' found_q_costs = True m.qg_operating_cost[gen_name] = \ sum(v*m.qg[gen_name]**i for i, v in q_costs[gen_name]['values'].items()) if not found_q_costs: del m.qg_operating_cost
def generate_model(data): h = int(data['hour']) y = float(data['y']) model = pyo.ConcreteModel() model.asymptote = pyo.Var(initialize=15) model.rate_constant = pyo.Var(initialize=0.5) def response_rule(m): expr = m.asymptote * (1 - pyo.exp(-m.rate_constant * h)) return expr model.response_function = pyo.Expression(rule=response_rule) def SSE_rule(m): return (y - m.response_function) ** 2 def ComputeFirstStageCost_rule(m): return 0 model.FirstStageCost = pyo.Expression(rule=ComputeFirstStageCost_rule) model.SecondStageCost = pyo.Expression(rule=SSE_rule) def total_cost_rule(model): return model.FirstStageCost + model.SecondStageCost # This objective is not needed by parmest model.Total_Cost_Objective = pyo.Objective(rule=total_cost_rule, sense=pyo.minimize) return model
def create_basic_dense_qp(G, A, b, c, complicated_var_ids): nx = G.shape[0] nl = A.shape[0] model = aml.ConcreteModel() model.var_ids = range(nx) model.complicated_var_ids = complicated_var_ids model.con_ids = range(nl) model.x = aml.Var(model.var_ids, initialize=0.0) model.x[0].value = 1.0 model.x[0].setlb(-100.0) model.x[0].setub(100.0) model.z = aml.Var(model.complicated_var_ids, initialize=0.0) model.hessian_f = aml.Param(model.var_ids, model.var_ids, mutable=True, rule=lambda m, i, j: G[i, j]) model.jacobian_c = aml.Param(model.con_ids, model.var_ids, mutable=True, rule=lambda m, i, j: A[i, j]) model.rhs = aml.Param(model.con_ids, mutable=True, rule=lambda m, i: b[i]) model.grad_f = aml.Param(model.var_ids, mutable=True, rule=lambda m, i: c[i]) def equality_constraint_rule(m, i): return sum(m.jacobian_c[i, j] * m.x[j] for j in m.var_ids) == m.rhs[i] model.equalities = aml.Constraint(model.con_ids, rule=equality_constraint_rule) def fixing_constraints_rule(m, i): return m.z[i] == m.x[i] model.fixing_constraints = aml.Constraint(model.complicated_var_ids, rule=fixing_constraints_rule) def second_stage_cost_rule(m): accum = 0.0 for i in m.var_ids: accum += m.x[i] * sum(m.hessian_f[i, j] * m.x[j] for j in m.var_ids) accum *= 0.5 accum += sum(m.x[j] * m.grad_f[j] for j in m.var_ids) return accum model.FirstStageCost = aml.Expression(expr=0.0) model.SecondStageCost = aml.Expression(rule=second_stage_cost_rule) model.obj = aml.Objective(expr=model.FirstStageCost + model.SecondStageCost, sense=aml.minimize) return model
def addExpressions(self, model): """ Add specific expressions for MCKP problems @ In, model, pyomo model instance, pyomo abstract model @ Out, model, pyomo model instance, pyomo abstract model """ model = ModelBase.addExpressions(self, model) model.firstStageCost = pyomo.Expression(rule=self.computeFirstStageCost) model.secondStageCost = pyomo.Expression(rule=self.computeSecondStageCost) return model
def _create_parmest_model(self, data): """ Modify the Pyomo model for parameter estimation """ from pyomo.core import Objective model = self.model_function(data) if (len(self.theta_names) == 1) and (self.theta_names[0] == 'parmest_dummy_var'): model.parmest_dummy_var = pyo.Var(initialize=1.0) for i, theta in enumerate(self.theta_names): # First, leverage the parser in ComponentUID to locate the # component. If that fails, fall back on the original # (insecure) use of 'eval' var_cuid = ComponentUID(theta) var_validate = var_cuid.find_component_on(model) if var_validate is None: logger.warning( "theta_name[%s] (%s) was not found on the model", (i, theta)) else: try: # If the component that was found is not a variable, # this will generate an exception (and the warning # in the 'except') var_validate.fixed = False # We want to standardize on the CUID string # representation (which is what PySP will use # internally) self.theta_names[i] = repr(var_cuid) except: logger.warning(theta + ' is not a variable') if self.obj_function: for obj in model.component_objects(Objective): obj.deactivate() def FirstStageCost_rule(model): return 0 model.FirstStageCost = pyo.Expression(rule=FirstStageCost_rule) model.SecondStageCost = pyo.Expression( rule=_SecondStateCostExpr(self.obj_function, data)) def TotalCost_rule(model): return model.FirstStageCost + model.SecondStageCost model.Total_Cost_Objective = pyo.Objective(rule=TotalCost_rule, sense=pyo.minimize) self.parmest_model = model return model
def declare_expr(exprname, model, index_set, **kwargs): # create var if index set is None if index_set is None: model.add_component(exprname, pe.Expression(**kwargs)) # transform the index set into a Pyomo Set else: pyomo_index_set = pe.Set(initialize=index_set, ordered=True) model.add_component("_expr_{}_index_set".format(exprname), pyomo_index_set) # now create the expr model.add_component(exprname, pe.Expression(pyomo_index_set, **kwargs))
def test_nested_named_expressions(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=0.23) m.y = pyo.Var(initialize=0.88) m.a = pyo.Expression(expr=(m.x + 1)**2) m.b = pyo.Expression(expr=3 * (m.a + m.y)) e = 2 * m.a + 2 * m.b + 2 * m.b + 2 * m.a derivs = reverse_ad(e) symbolic = reverse_sd(e) self.assertAlmostEqual(derivs[m.x], pyo.value(symbolic[m.x]), tol + 3) self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol) self.assertAlmostEqual(derivs[m.y], pyo.value(symbolic[m.y]), tol + 3) self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
def constraint_optimization_against_two_values(om: solph.Model, limit: float) -> solph.Model: """ Function for optimization against two parameters (e.g. monetary, emissions) :param om: oemof solph model to which the constraints will be \ added :type om: oemof.solph.Model :param limit: maximum value for the second parameter for the \ whole energysystem :type limit: int :return: - **om** (oemof.solph.Model) - oemof solph Model within \ the constraints """ import pyomo.environ as po from oemof.solph.plumbing import sequence invest_flows = {} for (i, o) in om.flows: if hasattr(om.flows[i, o].investment, "periodical_constraint_costs"): invest_flows[(i, o)] = om.flows[i, o].investment limit_name = "invest_limit_" + "space" setattr(om, limit_name, po.Expression( expr=sum(om.InvestmentFlow.invest[inflow, outflow] * getattr(invest_flows[inflow, outflow], "periodical_constraint_costs") for (inflow, outflow) in invest_flows ))) ############ flows = {} for (i, o) in om.flows: if hasattr(om.flows[i, o], "emission_factor"): flows[(i, o)] = om.flows[i, o] limit_name1 = "integral_limit_" + "emission_factor" setattr(om, limit_name1, po.Expression( expr=sum(om.flow[inflow, outflow, t] * om.timeincrement[t] * sequence(getattr(flows[inflow, outflow], "emission_factor"))[t] for (inflow, outflow) in flows for t in om.TIMESTEPS))) setattr(om, limit_name + "_constraint", po.Constraint( expr=((getattr(om, limit_name) + getattr(om, limit_name1)) <= limit))) return om
def __init__(self, f_i, q_i, T, q_ref=None, f_ref=None, T_ref=None, **kwargs): """ :param kwargs: passed to :code:`pyo.ConcreteModel` """ pyo.ConcreteModel.__init__(self, **kwargs) assert len(f_i) == len(q_i), 'Inconsistent input data' assert len(f_i) == len(T), 'Inconsistent number of temperatures' self.f_i = f_i self.q_i = q_i self.T = T self.q_ref = q_ref self.f_ref = f_ref self.T_ref = T_ref self.points = pyo.Set(initialize=list(range(len(f_i))), ordered=True) # override defaults if self.q_ref is None: self.q_ref = float(max(q_i)) if self.f_ref is None: self.f_ref = float(max(f_i)) if self.T_ref is None: self.T_ref = float(max(T)) self.f_i_star = [i / self.f_ref for i in self.f_i] self.theta = [i / self.q_ref for i in self.q_i] self.T_star = [i / self.T_ref for i in self.T] self.theta_calc = pyo.Var(self.points, initialize=1., bounds=(0., None)) self.x_data_dimensionless = [ (i, j) for i, j in zip(self.f_i_star, self.T_star) ] self.q_calc = pyo.Expression(self.points, rule=UnaryIsotherm.q_calc_expr) self.R2 = pyo.Expression(expr=self.R2_rule()) self.objective = pyo.Objective(expr=self.objective_rule_pyomo(), sense=pyo.minimize) self.has_isotherm_variables = False
def model(): m = pyo.ConcreteModel() m.w = pyo.Var([1, 2, 3], ["a", "b"], initialize=4, units=pyo.units.kg) m.x = pyo.Var([1, 2, 3], initialize=5, units=pyo.units.kg) m.y = pyo.Var(initialize=6, units=pyo.units.s) m.z = pyo.Var(initialize=7) m.e = pyo.Expression(expr=m.w[1, "a"] / m.x[1]) m.f = pyo.Expression(expr=m.x[1] / m.y) @m.Expression([1, 2, 3], ["a", "b"]) def g(b, i, j): return m.w[i, j] / m.x[i] * 100 return m
def __init__(self, *args, **kwargs): UnaryIsotherm.__init__(self, *args, **kwargs) # add variables self.H_i_star = pyo.Var(initialize=self.initial_guess_H_i_star()) self.A_i = pyo.Var(initialize=self.initial_guess_A_i()) self.q_mi_star = pyo.Var(initialize=self.initial_guess_q_mi_star()) # add expressions for dimensional quantities self.q_mi = pyo.Expression(expr=self.q_mi_star * self.q_ref) self.k_i_inf = pyo.Expression(expr=pyo.exp(self.A_i) / self.f_ref) self.dH_i = pyo.Expression(expr=R * self.T_ref * self.H_i_star) self.isotherm_eq = pyo.Constraint(self.points, rule=LangmuirUnary.isotherm_eq_rule) self.has_isotherm_variables = True
def rooney_biegler_model(data): """This function generates an instance of the rooney & biegler Pyomo model using 'data' as the input argument Parameters ---------- data: pandas DataFrame, list of dictionaries, or list of json file names Data that is used to build an instance of the Pyomo model Returns ------- m: an instance of the Pyomo model for estimating parameters and covariance """ model = pyo.ConcreteModel() model.asymptote = pyo.Var(initialize=15) model.rate_constant = pyo.Var(initialize=0.5) def response_rule(m, h): expr = m.asymptote * (1 - pyo.exp(-m.rate_constant * h)) return expr model.response_function = pyo.Expression(data.hour, rule=response_rule) return model
def _get_base_model(self): model = aml.ConcreteModel() model.x = aml.Var() model.y = aml.Var() model.d1 = aml.Param(mutable=True, initialize=0.0) model.d2 = aml.Param(mutable=True, initialize=0.0) model.d3 = aml.Param(mutable=True, initialize=0.0) model.cost = aml.Expression([1, 2]) model.cost[1].expr = model.x model.cost[2].expr = model.d1 * model.y model.o = aml.Objective(expr=model.cost[1] + model.cost[2]) model.c1 = aml.Constraint(expr=model.x >= 0) model.c2 = aml.Constraint(expr=model.y * model.d2 >= model.d3) model.varstage = VariableStageAnnotation() model.varstage.declare(model.x, 1) model.varstage.declare(model.y, 2) model.stagecost = StageCostAnnotation() model.stagecost.declare(model.cost[1], 1) model.stagecost.declare(model.cost[2], 2) model.stochdata = StochasticDataAnnotation() model.stochdata.declare(model.d1, distribution=TableDistribution([0.0, 1.0])) model.stochdata.declare(model.d2, distribution=TableDistribution([0.0, 1.0])) model.stochdata.declare(model.d3, distribution=TableDistribution([0.0, 1.0])) return model
def model(): m = pyo.ConcreteModel() m.x = pyo.Var([1, 2, 3, 4], initialize=2) m.y = pyo.Var(initialize=3) m.z = pyo.Var([1, 2, 3, 4], initialize=0) m.e = pyo.Expression(expr=m.x[1] + m.x[2]) m.z.fix() m.z[4] = 4.0 # In the first round this becomes x[1].fix(m.z[1]) m.c1 = pyo.Constraint(expr=m.z[1] == m.x[1]) # In the first round this beconmes y.fix(m.z[2]) m.c2 = pyo.Constraint(expr=m.z[2] == m.y) # In the second round this becomes x[2].fix(m.z[3]-m.x[1]) m.c3 = pyo.Constraint(expr=m.z[3] == m.e) # This constraint is nonlinear but m.x[1] will be fixed m.c4 = pyo.Constraint(expr=m.z[4] == m.x[3]**2 + m.x[1]) # This constraint is eliminated by a substitution, x[3] and x[4] are not # fixed, so it's a linear equation with two variables. This should be in the # second round after x[1] becomes fixed in the first m.c5 = pyo.Constraint(expr=m.z[4] == m.x[4] + m.x[1] + m.x[3]) # Solution m.x[1] = 0 m.x[2] = 0 m.x[3] = 2 m.x[4] = 2 m.y = 0 # make a dict to check variable values against (vars and named expressions) m.sol = {} for v in m.component_data_objects((pyo.Var, pyo.Expression)): m.sol[id(v)] = pyo.value(v) return m
def build_process_costs(self): self.total_capital_cost = pyo.Expression( expr = self.aggregate_capital_cost, doc='Total capital cost') self.total_investment_cost = pyo.Var( initialize=1e3, domain=pyo.NonNegativeReals, doc='Total investment cost', units=self.base_currency) self.maintenance_labor_chemical_operating_cost = pyo.Var( initialize=1e3, domain=pyo.NonNegativeReals, doc='Maintenance-labor-chemical operating cost', units=self.base_currency/self.base_period) self.total_operating_cost= pyo.Var( initialize=1e3, domain=pyo.NonNegativeReals, doc='Total operating cost', units=self.base_currency/self.base_period) self.total_investment_cost_constraint = pyo.Constraint(expr = \ self.total_investment_cost == self.factor_total_investment * self.total_capital_cost) self.maintenance_labor_chemical_operating_cost_constraint = pyo.Constraint(expr = \ self.maintenance_labor_chemical_operating_cost == self.factor_maintenance_labor_chemical * self.total_investment_cost) self.total_operating_cost_constraint = pyo.Constraint(expr = \ self.total_operating_cost == self.maintenance_labor_chemical_operating_cost \ + self.aggregate_fixed_operating_cost \ + self.aggregate_variable_operating_cost \ + sum(self.aggregate_flow_costs.values())*self.load_factor )
def declare_expression_qg_operating_cost(model, index_set, q_costs, pw_formulation='delta'): """ Create the Expression objects to represent the operating costs for the reactive power of each of the generators. """ m = model expr_set = decl.declare_set('_expr_qg_operating_cost', model=model, index_set=index_set) m.qg_operating_cost = pe.Expression(expr_set) for gen_name in expr_set: if gen_name in q_costs: if q_costs[gen_name]['cost_curve_type'] == 'polynomial': m.qg_operating_cost[gen_name] = sum(v*m.qg[gen_name]**i for i, v in q_costs[gen_name]['values'].items()) elif q_costs[gen_name]['cost_curve_type'] == 'piecewise': if pw_formulation == 'delta': q_min = m.qg[gen_name].lb q_max = m.qg[gen_name].ub curve = q_costs[gen_name] cleaned_values = tx_utils.validate_and_clean_cost_curve(curve=curve, curve_type='cost_curve', p_min=q_min, p_max=q_max, gen_name=gen_name) expr = cleaned_values[0][1] for ndx, ((o1, c1), (o2, c2)) in enumerate(zip(cleaned_values, cleaned_values[1:])): slope = (c2 - c1) / (o2 - o1) expr += slope * m.delta_pg[gen_name, ndx] m.qg_operating_cost[gen_name] = expr else: m.qg_operating_cost[gen_name] = m.qg_cost[gen_name] else: raise ValueError(f"Unrecognized cost_cureve_type: {q_costs[gen_name]['cost_curve_type']}") else: m.qg_operating_cost[gen_name] = 0
def test_passing_indexed_component_not_list(self): model = pyo.ConcreteModel() model.x = pyo.Var(bounds=(-5.0, 5.0)) model.S = pyo.Set(initialize=['A', 'B'], ordered=True) model.y = pyo.Var(model.S, bounds=(-100.0, 100.0)) model.obj_expr = pyo.Expression(expr=model.y['A']) model.obj = pyo.Objective(expr=model.obj_expr) x_points = [-5.0, 5.0] model.under_estimators = pyo.ConstraintList() for xp in x_points: m = 2 * xp b = -(xp ** 2) model.under_estimators.add(model.y['A'] >= m * model.x + b) model.con = pyo.Constraint(expr=model.y['A'] == 1 + model.y['B']) solver = pyo.SolverFactory('ipopt') lower, upper = coramin.domain_reduction.perform_obbt(model=model, solver=solver, varlist=model.y, update_bounds=True) self.assertAlmostEqual(pyo.value(model.x.lb), -5.0, delta=1e-6) self.assertAlmostEqual(pyo.value(model.x.ub), 5.0, delta=1e-6) self.assertAlmostEqual(pyo.value(model.y['A'].lb), -25.0, delta=1e-6) self.assertAlmostEqual(pyo.value(model.y['A'].ub), 100.0, delta=1e-6) self.assertAlmostEqual(pyo.value(model.y['B'].lb), -26.0, delta=1e-6) self.assertAlmostEqual(pyo.value(model.y['B'].ub), 99.0, delta=1e-6) self.assertAlmostEqual(lower[0], -25.0, delta=1e-6) self.assertAlmostEqual(upper[0], 100.0, delta=1e-6) self.assertAlmostEqual(lower[1], -26.0, delta=1e-6) self.assertAlmostEqual(upper[1], 99.0, delta=1e-6)
def test_quad(self): model = pyo.ConcreteModel() model.x = pyo.Var(bounds=(-5.0, 5.0)) model.y = pyo.Var(bounds=(-100.0, 100.0)) model.obj_expr = pyo.Expression(expr=model.y) model.obj = pyo.Objective(expr=model.obj_expr) x_points = [-5.0, 5.0] model.under_estimators = pyo.ConstraintList() for xp in x_points: m = 2*xp b = -(xp**2) model.under_estimators.add(model.y >= m*model.x + b) solver = pyo.SolverFactory('ipopt') (lower, upper) = coramin.domain_reduction.perform_obbt(model=model, solver=solver, varlist=[model.x, model.y], update_bounds=True) self.assertAlmostEqual(pyo.value(model.x.lb), -5.0, delta=1e-6) self.assertAlmostEqual(pyo.value(model.x.ub), 5.0, delta=1e-6) self.assertAlmostEqual(pyo.value(model.y.lb), -25.0, delta=1e-6) self.assertAlmostEqual(pyo.value(model.y.ub), 100.0, delta=1e-6) self.assertAlmostEqual(lower[0], -5.0, delta=1e-6) self.assertAlmostEqual(upper[0], 5.0, delta=1e-6) self.assertAlmostEqual(lower[1], -25.0, delta=1e-6) self.assertAlmostEqual(upper[1], 100.0, delta=1e-6)
def percent_reduction_for_each_lrseg_expr(model) -> pyo.ConcreteModel: """ Percent Relative Load Reduction (quantified for each lrseg) """ # The model parameter 'originalload[s, p]' is required for this expression. model = original_load_for_each_lrseg_expr(model) model = new_load_for_each_lrseg_expr(model) # loading before any new BMPs have been implemented # model.originalload = pyo.Param(model.LRSEGS, # model.PLTNTS, # initialize=lambda m, s, p: m.original_load_for_each_lrseg_expr[s, p]) # Relative load reductions must be greater than the specified target percentages (Theta) def percent_reduction_rule_for_each_lrseg(mdl, s, p): # Some lrsegs have 0 total load for some nutrients # E.g. N24031PM0_4640_4820 = Cabin John Creek, in Montgomery County # has 0 originalload for phosphorus. This causes a ZeroDivisionError when Pyomo # tries to generate an expression for this rule. # To avoid this, we set the percent reduction here to zero no matter what, since # we can assume newload never increases from zero to a positive value. if mdl.originalload[s, p] != 0: temp = ((mdl.original_load_for_each_lrseg_expr[s, p] - mdl.new_load_for_each_lrseg_expr[s, p]) / mdl.original_load_for_each_lrseg_expr[s, p]) * 100 else: temp = 0 return temp model.percent_reduction_for_each_lrseg_expr = pyo.Expression( model.PLTNTS, model.LRSEGS, rule=percent_reduction_rule_for_each_lrseg) return model
def add_data_match_obj(model, df_meta, bin_stdev): @model.Expression(model.data_param.index_set()) def err_abs(b, tag): return df_meta[tag]["reference"][0] - model.data_param[tag] @model.Expression(model.data_param.index_set()) def err_rel(b, tag): return model.err_abs[tag] / model.data_param[tag] @model.Expression(model.data_param.index_set()) def err_pct(b, tag): return model.err_rel[tag] * 100 @model.Expression(model.data_param.index_set()) def err_stdev(b, tag): return model.err_abs[tag] / bin_stdev[model.data_bin][tag] model.obj_weight = pyo.Param(model.data_param.index_set(), initialize=1, mutable=True) n = len(model.data_param.index_set()) model.obj_datarec = pyo.Objective(expr=pyo.sqrt( sum(model.obj_weight[t] * (model.err_stdev[t])**2 for t in model.data_param) / n)) model.obj_expr = pyo.Expression(expr=pyo.sqrt( sum(model.obj_weight[t] * (model.err_stdev[t])**2 for t in model.data_param) / n))
def _create_integrals(self): _model = self._model _parameters = self._parameters def _force_expr(_mod, _pos): # to offset for having optimum at the target velocity steady_motor_force_coef = 2 * _mod.air_fric_coef * _mod.v_target ** 3 # THERE SHOULD BE A FACTOR 2 IN THERE BUT IF IT'S THERE IT MESSES IT UP ARGH. AAAAARGH i found it. # add a constant to show cost departure from equilibrium rather than abs cost_balancer = (_mod.air_fric_coef * _mod.v_target ** 2 - _mod.rolling_friction[_pos] - _mod.gravity[_pos] + steady_motor_force_coef / _mod.v_target) return (_mod.motor_force[_pos] + steady_motor_force_coef * _mod.v_inv[_pos] - cost_balancer if _pos < _parameters["episode_dist_end"] else 0) # for soft constraint on velocity _model.v_softlim = env.Var(_model.x_local, domain=env.Reals, initialize=BaseModel._create_const_rule(0)) _model.v_softconstraint = env.Constraint(_model.x_local, rule=BaseModel._create_soft_constraint_fn( _model.v, _model.v_softlim, (_model.v_soft_min, _model.v_soft_max))) def _motor_smooth_expr(_mod, _pos): return (_mod.d2m_dx2[_pos] ** 2 + _mod.d2b_dx2[_pos] ** 2 if _pos < _parameters["episode_dist_end"] else 0) def _vel_expr(_mod, _pos): return (abs(_mod.v_softlim[_pos])**2 * _mod.v_inv[_pos] if _pos < _parameters["episode_dist_end"] else 0) def _v_2ndtimederiv_expr(_mod, _pos): return (_mod.v[_pos]*(_mod.dv_dx[_pos]**2 + _mod.v[_pos] * _mod.dv_dx[_pos].derivative(_mod.x_local) )**2 if _pos < _parameters["episode_dist_end"] else 0) _model.energy_integral = dae.Integral(_model.x_local, wrt=_model.x_local, rule=_force_expr) _model.velocity_integral = dae.Integral(_model.x_local, wrt=_model.x_local, rule=_vel_expr) _model.acc_smooth_integral = dae.Integral(_model.x_local, wrt=_model.x_local, rule=_v_2ndtimederiv_expr) _model.motor_smooth_integral= dae.Integral(_model.x_local, wrt=_model.x_local, rule=_motor_smooth_expr) _model.inst_cost = env.Expression(_model.x_local, rule=lambda _mod, _pos: ( _mod.motor_cost_coef * _force_expr(_mod, _pos) + _mod.vel_cost_coef * _vel_expr(_mod, _pos) + _mod.acc_cost_coef * _v_2ndtimederiv_expr(_mod, _pos) + _mod.motor_smooth_coef * _motor_smooth_expr(_mod, _pos) # to compensate for the cost compensation - _mod.gravity[_pos] - _mod.rolling_friction[_pos]))
def model(self): m = pyo.ConcreteModel() m.fs = fs = pyo.Block() fs.input = pyo.Var(['a', 'b'], within=pyo.UnitInterval, initialize=0.5) fs.output = pyo.Var(['c', 'd'], within=pyo.UnitInterval, initialize=0.5) fs.slack = pyo.Var(['ab_slack', 'cd_slack'], bounds=(0, 0), initialize=0.0) fs.slack_penalty = pyo.Param(default=1000., mutable=True, within=pyo.PositiveReals) fs.ab_constr = pyo.Constraint( expr=(fs.output['c'] + fs.slack['ab_slack'] == 2 * fs.input['a'])) fs.cd_constr = pyo.Constraint( expr=(fs.output['d'] + fs.slack['cd_slack'] == 3 * fs.input['b'])) fs.performance = pyo.Expression(expr=pyo.summation(fs.output)) m.objective = pyo.Objective( expr=m.fs.performance - m.fs.slack_penalty * pyo.summation(m.fs.slack), sense=pyo.maximize) return m
def rooney_biegler_model_alternate(data): ''' Alternate model definition used in a unit test Here, the fitted parameters are defined as a single variable over a set A bit silly for this specific example ''' model = pyo.ConcreteModel() model.var_names = pyo.Set( initialize=['asymptote', 'rate_constant']) model.theta = pyo.Var(model.var_names, initialize={ 'asymptote': 15, 'rate_constant': 0.5 }) model.theta[ 'asymptote'].fixed = True # parmest will unfix theta variables, even when they are indexed model.theta['rate_constant'].fixed = True def response_rule(m, h): expr = m.theta['asymptote'] * ( 1 - pyo.exp(-m.theta['rate_constant'] * h)) return expr model.response_function = pyo.Expression(data.hour, rule=response_rule) def SSE_rule(m): return sum((data.y[i] - m.response_function[data.hour[i]])**2 for i in data.index) model.SSE = pyo.Objective(rule=SSE_rule, sense=pyo.minimize) return model
def __init__( self, interval_set, params: dict, ): super().__init__() ## Setup self.id = params["name"] self.objective_terms = {} self.block = aml.Block(concrete=True) ## Params # Decide if we want load as mutable param - need to use param object # not sure what difference is with raw numpy - may be pyomo mutability - check this # self.load = aml.parameter_dict() self.block.load = params["load"] # for interval in interval_set: # self.load[interval] = params["load"][interval] ## Expressions def _net_export(b, idx): return -b.load[idx] self.block.net_export = aml.Expression(interval_set, rule=_net_export)
def total_cost_expr(model) -> pyo.ConcreteModel: """ Total Cost Expression """ def total_cost_rule(mdl): return pyo.quicksum((mdl.tau[b] * mdl.x[b, s, u, h]) for b in mdl.BMPS for s, u, h in mdl.PARCELS) model.total_cost_expr = pyo.Expression(rule=total_cost_rule) return model