Skip to content

Commit

Permalink
Merge pull request #2852 from jsiirola/nlwriter-sos
Browse files Browse the repository at this point in the history
Resolve error identifying vars in indexed SOS
  • Loading branch information
michaelbynum authored May 30, 2023
2 parents 4743218 + 2d1805d commit 68e4410
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pyomo/repn/plugins/nl_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
71 changes: 71 additions & 0 deletions pyomo/repn/tests/ampl/test_nlv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
Constraint,
Expression,
)
import pyomo.environ as pyo

_invalid_1j = r'InvalidNumber\((\([-+0-9.e]+\+)?1j\)?\)'

Expand Down Expand Up @@ -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(),
)
Expand Down

0 comments on commit 68e4410

Please sign in to comment.