diff --git a/pyomo/repn/plugins/nl_writer.py b/pyomo/repn/plugins/nl_writer.py index c39a216f57f..73465a54bbb 100644 --- a/pyomo/repn/plugins/nl_writer.py +++ b/pyomo/repn/plugins/nl_writer.py @@ -684,7 +684,7 @@ def write(self, model): # variable order because the SOS constraint *could* reference a # variable not yet seen in the model. for block in component_map[SOSConstraint]: - for sos in block.component_objects( + for sos in block.component_data_objects( SOSConstraint, active=True, descend_into=False, sort=sorter ): for v in sos.variables: diff --git a/pyomo/repn/tests/ampl/test_nlv2.py b/pyomo/repn/tests/ampl/test_nlv2.py index fef17b49fab..4c00d86fad1 100644 --- a/pyomo/repn/tests/ampl/test_nlv2.py +++ b/pyomo/repn/tests/ampl/test_nlv2.py @@ -35,6 +35,7 @@ Constraint, Expression, ) +import pyomo.environ as pyo _invalid_1j = r'InvalidNumber\((\([-+0-9.e]+\+)?1j\)?\)' @@ -955,6 +956,76 @@ def test_linear_constraint_npv_const(self): J0 2 0 5 1 10 +""", + OUT.getvalue(), + ) + ) + + def test_indexed_sos_constraints(self): + # This tests the example from issue #2827 + m = pyo.ConcreteModel() + m.A = pyo.Set(initialize=[1]) + m.B = pyo.Set(initialize=[1, 2, 3]) + m.C = pyo.Set(initialize=[1]) + + m.param_cx = pyo.Param(m.A, initialize={1: 1}) + m.param_cy = pyo.Param(m.B, initialize={1: 2, 2: 3, 3: 1}) + + m.x = pyo.Var(m.A, domain=pyo.NonNegativeReals, bounds=(0, 40)) + m.y = pyo.Var(m.B, domain=pyo.NonNegativeIntegers) + + @m.Objective() + def OBJ(m): + return sum(m.param_cx[a] * m.x[a] for a in m.A) + sum( + m.param_cy[b] * m.y[b] for b in m.B + ) + + m.y[3].bounds = (2, 3) + + m.mysos = pyo.SOSConstraint( + m.C, var=m.y, sos=1, index={1: [2, 3]}, weights={2: 25.0, 3: 18.0} + ) + + OUT = io.StringIO() + with LoggingIntercept() as LOG: + nl_writer.NLWriter().write(m, OUT, symbolic_solver_labels=True) + self.assertEqual(LOG.getvalue(), "") + self.assertEqual( + *nl_diff( + """g3 1 1 0 # problem unknown + 4 0 1 0 0 # vars, constraints, objectives, ranges, eqns + 0 0 0 0 0 0 # nonlinear constrs, objs; ccons: lin, nonlin, nd, nzlb + 0 0 # network constraints: nonlinear, linear + 0 0 0 # nonlinear vars in constraints, objectives, both + 0 0 0 1 # linear network variables; functions; arith, flags + 0 3 0 0 0 # discrete variables: binary, integer, nonlinear (b,c,o) + 0 4 # nonzeros in Jacobian, obj. gradient + 3 4 # max name lengths: constraints, variables + 0 0 0 0 0 # common exprs: b,c,o,c1,o1 +S0 2 sosno +2 1 +3 1 +S0 2 ref +2 25.0 +3 18.0 +O0 0 #OBJ +n0 +x0 # initial guess +r #0 ranges (rhs's) +b #4 bounds (on variables) +0 0 40 #x[1] +2 0 #y[1] +2 0 #y[2] +0 2 3 #y[3] +k3 #intermediate Jacobian column lengths +0 +0 +0 +G0 4 #OBJ +0 1 +1 2 +2 3 +3 1 """, OUT.getvalue(), )