Skip to content

Commit 15f030c

Browse files
authored
Merge branch 'main' into highs_log
2 parents 4cff5ff + f55b042 commit 15f030c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3004
-1692
lines changed

Diff for: doc/OnlineDocs/explanation/experimental/solvers.rst

+30-29
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,20 @@ with existing interfaces).
4040
:header-rows: 1
4141

4242
* - Solver
43-
- Name registered in the |br| ``pyomo.contrib.solver.factory.SolverFactory``
43+
- Name registered in the |br| ``pyomo.contrib.solver.common.factory.SolverFactory``
4444
- Name registered in the |br| ``pyomo.opt.base.solvers.LegacySolverFactory``
4545
* - Ipopt
4646
- ``ipopt``
4747
- ``ipopt_v2``
4848
* - Gurobi (persistent)
49-
- ``gurobi``
50-
- ``gurobi_v2``
49+
- ``gurobi_persistent``
50+
- ``gurobi_persistent_v2``
5151
* - Gurobi (direct)
5252
- ``gurobi_direct``
5353
- ``gurobi_direct_v2``
54+
* - HiGHS
55+
- ``highs``
56+
- ``highs``
5457

5558
Using the new interfaces through the legacy interface
5659
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +67,6 @@ be used with other Pyomo tools / capabilities.
6467
:skipif: not ipopt_available
6568

6669
import pyomo.environ as pyo
67-
from pyomo.contrib.solver.util import assert_optimal_termination
6870

6971
model = pyo.ConcreteModel()
7072
model.x = pyo.Var(initialize=1.5)
@@ -76,13 +78,14 @@ be used with other Pyomo tools / capabilities.
7678
model.obj = pyo.Objective(rule=rosenbrock, sense=pyo.minimize)
7779

7880
status = pyo.SolverFactory('ipopt_v2').solve(model)
79-
assert_optimal_termination(status)
81+
pyo.assert_optimal_termination(status)
8082
model.pprint()
8183

8284
.. testoutput::
8385
:skipif: not ipopt_available
8486
:hide:
8587

88+
...
8689
2 Var Declarations
8790
...
8891
3 Declarations: x y obj
@@ -114,6 +117,7 @@ future methods of specifying solver options are supported:
114117
:skipif: not ipopt_available
115118
:hide:
116119

120+
...
117121
2 Var Declarations
118122
...
119123
3 Declarations: x y obj
@@ -128,8 +132,7 @@ Here we use the new interface by importing it directly:
128132

129133
# Direct import
130134
import pyomo.environ as pyo
131-
from pyomo.contrib.solver.util import assert_optimal_termination
132-
from pyomo.contrib.solver.ipopt import Ipopt
135+
from pyomo.contrib.solver.solvers.ipopt import Ipopt
133136

134137
model = pyo.ConcreteModel()
135138
model.x = pyo.Var(initialize=1.5)
@@ -142,7 +145,7 @@ Here we use the new interface by importing it directly:
142145

143146
opt = Ipopt()
144147
status = opt.solve(model)
145-
assert_optimal_termination(status)
148+
pyo.assert_optimal_termination(status)
146149
# Displays important results information; only available through the new interfaces
147150
status.display()
148151
model.pprint()
@@ -165,8 +168,7 @@ Here we use the new interface by retrieving it from the new ``SolverFactory``:
165168

166169
# Import through new SolverFactory
167170
import pyomo.environ as pyo
168-
from pyomo.contrib.solver.util import assert_optimal_termination
169-
from pyomo.contrib.solver.factory import SolverFactory
171+
from pyomo.contrib.solver.common.factory import SolverFactory
170172

171173
model = pyo.ConcreteModel()
172174
model.x = pyo.Var(initialize=1.5)
@@ -179,7 +181,7 @@ Here we use the new interface by retrieving it from the new ``SolverFactory``:
179181

180182
opt = SolverFactory('ipopt')
181183
status = opt.solve(model)
182-
assert_optimal_termination(status)
184+
pyo.assert_optimal_termination(status)
183185
# Displays important results information; only available through the new interfaces
184186
status.display()
185187
model.pprint()
@@ -204,7 +206,6 @@ replace the existing (legacy) SolverFactory and utilities with the new
204206

205207
# Change default SolverFactory version
206208
import pyomo.environ as pyo
207-
from pyomo.contrib.solver.util import assert_optimal_termination
208209
from pyomo.__future__ import solver_factory_v3
209210

210211
model = pyo.ConcreteModel()
@@ -217,7 +218,7 @@ replace the existing (legacy) SolverFactory and utilities with the new
217218
model.obj = pyo.Objective(rule=rosenbrock, sense=pyo.minimize)
218219

219220
status = pyo.SolverFactory('ipopt').solve(model)
220-
assert_optimal_termination(status)
221+
pyo.assert_optimal_termination(status)
221222
# Displays important results information; only available through the new interfaces
222223
status.display()
223224
model.pprint()
@@ -245,13 +246,13 @@ recently incorporated into the redesigned NL writer. For example, you
245246
can control the NL writer in the new ``ipopt`` interface through the
246247
solver's ``writer_config`` configuration option:
247248

248-
.. autoclass:: pyomo.contrib.solver.ipopt.Ipopt
249+
.. autoclass:: pyomo.contrib.solver.solvers.ipopt.Ipopt
249250
:noindex:
250251
:members: solve
251252

252253
.. testcode::
253254

254-
from pyomo.contrib.solver.ipopt import Ipopt
255+
from pyomo.contrib.solver.solvers.ipopt import Ipopt
255256
opt = Ipopt()
256257
opt.config.writer_config.display()
257258

@@ -281,18 +282,18 @@ Interface Implementation
281282
------------------------
282283

283284
All new interfaces should be built upon one of two classes (currently):
284-
:class:`SolverBase<pyomo.contrib.solver.base.SolverBase>` or
285-
:class:`PersistentSolverBase<pyomo.contrib.solver.base.PersistentSolverBase>`.
285+
:class:`SolverBase<pyomo.contrib.solver.common.base.SolverBase>` or
286+
:class:`PersistentSolverBase<pyomo.contrib.solver.common.base.PersistentSolverBase>`.
286287

287288
All solvers should have the following:
288289

289-
.. autoclass:: pyomo.contrib.solver.base.SolverBase
290+
.. autoclass:: pyomo.contrib.solver.common.base.SolverBase
290291
:noindex:
291292
:members:
292293

293294
Persistent solvers include additional members as well as other configuration options:
294295

295-
.. autoclass:: pyomo.contrib.solver.base.PersistentSolverBase
296+
.. autoclass:: pyomo.contrib.solver.common.base.PersistentSolverBase
296297
:noindex:
297298
:show-inheritance:
298299
:members:
@@ -301,12 +302,12 @@ Results
301302
-------
302303

303304
Every solver, at the end of a
304-
:meth:`solve<pyomo.contrib.solver.base.SolverBase.solve>` call, will
305-
return a :class:`Results<pyomo.contrib.solver.results.Results>`
305+
:meth:`solve<pyomo.contrib.solver.common.base.SolverBase.solve>` call, will
306+
return a :class:`Results<pyomo.contrib.solver.common.results.Results>`
306307
object. This object is a :py:class:`pyomo.common.config.ConfigDict`,
307308
which can be manipulated similar to a standard ``dict`` in Python.
308309

309-
.. autoclass:: pyomo.contrib.solver.results.Results
310+
.. autoclass:: pyomo.contrib.solver.common.results.Results
310311
:noindex:
311312
:show-inheritance:
312313
:members:
@@ -318,12 +319,12 @@ Termination Conditions
318319

319320
Pyomo offers a standard set of termination conditions to map to solver
320321
returns. The intent of
321-
:class:`TerminationCondition<pyomo.contrib.solver.results.TerminationCondition>`
322+
:class:`TerminationCondition<pyomo.contrib.solver.common.results.TerminationCondition>`
322323
is to notify the user of why the solver exited. The user is expected
323-
to inspect the :class:`Results<pyomo.contrib.solver.results.Results>`
324+
to inspect the :class:`Results<pyomo.contrib.solver.common.results.Results>`
324325
object or any returned solver messages or logs for more information.
325326

326-
.. autoclass:: pyomo.contrib.solver.results.TerminationCondition
327+
.. autoclass:: pyomo.contrib.solver.common.results.TerminationCondition
327328
:noindex:
328329
:show-inheritance:
329330

@@ -333,13 +334,13 @@ Solution Status
333334

334335
Pyomo offers a standard set of solution statuses to map to solver
335336
output. The intent of
336-
:class:`SolutionStatus<pyomo.contrib.solver.results.SolutionStatus>`
337+
:class:`SolutionStatus<pyomo.contrib.solver.common.results.SolutionStatus>`
337338
is to notify the user of what the solver returned at a high level. The
338339
user is expected to inspect the
339-
:class:`Results<pyomo.contrib.solver.results.Results>` object or any
340+
:class:`Results<pyomo.contrib.solver.common.results.Results>` object or any
340341
returned solver messages or logs for more information.
341342

342-
.. autoclass:: pyomo.contrib.solver.results.SolutionStatus
343+
.. autoclass:: pyomo.contrib.solver.common.results.SolutionStatus
343344
:noindex:
344345
:show-inheritance:
345346

@@ -351,7 +352,7 @@ Solutions can be loaded back into a model using a ``SolutionLoader``. A specific
351352
loader should be written for each unique case. Several have already been
352353
implemented. For example, for ``ipopt``:
353354

354-
.. autoclass:: pyomo.contrib.solver.ipopt.IpoptSolutionLoader
355+
.. autoclass:: pyomo.contrib.solver.solvers.ipopt.IpoptSolutionLoader
355356
:noindex:
356357
:members:
357358
:show-inheritance:

Diff for: doc/OnlineDocs/explanation/solvers/pyros.rst

+28-24
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,9 @@ Observe that the log contains the following information:
924924
are included in parentheses, next to the total numbers
925925
of second-stage variables and state variables, respectively;
926926
note that "adjustable" has been abbreviated as "adj."
927+
The number of truly uncertain parameters detected during preprocessing
928+
is also noted in parentheses
929+
(in which "eff." is an abbreviation for "effective").
927930
* **Iteration log table** (lines 59--69).
928931
Summary information on the problem iterates and subproblem outcomes.
929932
The constituent columns are defined in detail in
@@ -961,21 +964,21 @@ Observe that the log contains the following information:
961964
:linenos:
962965
963966
==============================================================================
964-
PyROS: The Pyomo Robust Optimization Solver, v1.3.4.
965-
Pyomo version: 6.9.0
966-
Commit hash: unknown
967-
Invoked at UTC 2025-02-13T00:00:00.000000
967+
PyROS: The Pyomo Robust Optimization Solver, v1.3.6.
968+
Pyomo version: 6.9.2.dev0 (devel {pyros-effective-uncertain-params})
969+
Commit hash: 41cd797e0
970+
Invoked at UTC 2025-03-13T16:20:31.105320+00:00
968971
969972
Developed by: Natalie M. Isenberg (1), Jason A. F. Sherman (1),
970973
John D. Siirola (2), Chrysanthos E. Gounaris (1)
971974
(1) Carnegie Mellon University, Department of Chemical Engineering
972975
(2) Sandia National Laboratories, Center for Computing Research
973-
976+
974977
The developers gratefully acknowledge support from the U.S. Department
975978
of Energy's Institute for the Design of Advanced Energy Systems (IDAES).
976979
==============================================================================
977980
================================= DISCLAIMER =================================
978-
PyROS is still under development.
981+
PyROS is still under development.
979982
Please provide feedback and/or report any issues by creating a ticket at
980983
https://github.com/Pyomo/pyomo/issues/new/choose
981984
==============================================================================
@@ -1001,7 +1004,7 @@ Observe that the log contains the following information:
10011004
p_robustness={}
10021005
------------------------------------------------------------------------------
10031006
Preprocessing...
1004-
Done preprocessing; required wall time of 0.009s.
1007+
Done preprocessing; required wall time of 0.013s.
10051008
------------------------------------------------------------------------------
10061009
Model Statistics:
10071010
Number of variables : 62
@@ -1010,7 +1013,7 @@ Observe that the log contains the following information:
10101013
Second-stage variables : 6 (6 adj.)
10111014
State variables : 18 (7 adj.)
10121015
Decision rule variables : 30
1013-
Number of uncertain parameters : 4
1016+
Number of uncertain parameters : 4 (4 eff.)
10141017
Number of constraints : 52
10151018
Equality constraints : 24
10161019
Coefficient matching constraints : 0
@@ -1023,33 +1026,34 @@ Observe that the log contains the following information:
10231026
------------------------------------------------------------------------------
10241027
Itn Objective 1-Stg Shift 2-Stg Shift #CViol Max Viol Wall Time (s)
10251028
------------------------------------------------------------------------------
1026-
0 3.5838e+07 - - 5 1.8832e+04 0.412
1027-
1 3.5838e+07 1.2289e-09 1.5886e-12 5 2.8919e+02 0.992
1028-
2 3.6269e+07 3.1647e-01 1.0432e-01 4 2.9020e+02 1.865
1029-
3 3.6285e+07 7.6526e-01 2.2258e-01 0 2.3874e-12g 3.508
1029+
0 3.5838e+07 - - 5 1.8832e+04 0.693
1030+
1 3.5838e+07 1.2289e-09 1.5876e-12 5 3.7762e+04 1.514
1031+
2 3.6129e+07 2.7244e-01 3.6878e-01 3 1.1093e+02 2.486
1032+
3 3.6269e+07 3.7352e-01 4.3227e-01 1 2.7711e+01 3.667
1033+
4 3.6285e+07 7.6526e-01 2.8426e-11 0 4.3364e-05g 6.291
10301034
------------------------------------------------------------------------------
10311035
Robust optimal solution identified.
10321036
------------------------------------------------------------------------------
10331037
Timing breakdown:
1034-
1038+
10351039
Identifier ncalls cumtime percall %
10361040
-----------------------------------------------------------
1037-
main 1 3.509 3.509 100.0
1041+
main 1 6.291 6.291 100.0
10381042
------------------------------------------------------
1039-
dr_polishing 3 0.209 0.070 6.0
1040-
global_separation 27 0.590 0.022 16.8
1041-
local_separation 108 1.569 0.015 44.7
1042-
master 4 0.654 0.163 18.6
1043-
master_feasibility 3 0.083 0.028 2.4
1044-
preprocessing 1 0.009 0.009 0.3
1045-
other n/a 0.394 n/a 11.2
1043+
dr_polishing 4 0.334 0.083 5.3
1044+
global_separation 27 0.954 0.035 15.2
1045+
local_separation 135 3.046 0.023 48.4
1046+
master 5 1.027 0.205 16.3
1047+
master_feasibility 4 0.133 0.033 2.1
1048+
preprocessing 1 0.013 0.013 0.2
1049+
other n/a 0.785 n/a 12.5
10461050
======================================================
10471051
===========================================================
1048-
1052+
10491053
------------------------------------------------------------------------------
10501054
Termination stats:
1051-
Iterations : 4
1052-
Solve time (wall s) : 3.509
1055+
Iterations : 5
1056+
Solve time (wall s) : 6.291
10531057
Final objective value : 3.6285e+07
10541058
Termination condition : pyrosTerminationCondition.robust_optimal
10551059
------------------------------------------------------------------------------

Diff for: doc/OnlineDocs/reference/topical/appsi/appsi.rst

+17-8
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ example of using an APPSI solver interface.
2424

2525
.. code-block:: python
2626
27-
>>> import pyomo.environ as pe
27+
>>> import pyomo.environ as pyo
2828
>>> from pyomo.contrib import appsi
2929
>>> import numpy as np
3030
>>> from pyomo.common.timing import HierarchicalTimer
31-
>>> m = pe.ConcreteModel()
32-
>>> m.x = pe.Var()
33-
>>> m.y = pe.Var()
34-
>>> m.p = pe.Param(mutable=True)
35-
>>> m.obj = pe.Objective(expr=m.x**2 + m.y**2)
36-
>>> m.c1 = pe.Constraint(expr=m.y >= pe.exp(m.x))
37-
>>> m.c2 = pe.Constraint(expr=m.y >= (m.x - m.p)**2)
31+
>>> m = pyo.ConcreteModel()
32+
>>> m.x = pyo.Var()
33+
>>> m.y = pyo.Var()
34+
>>> m.p = pyo.Param(mutable=True)
35+
>>> m.obj = pyo.Objective(expr=m.x**2 + m.y**2)
36+
>>> m.c1 = pyo.Constraint(expr=m.y >= pyo.exp(m.x))
37+
>>> m.c2 = pyo.Constraint(expr=m.y >= (m.x - m.p)**2)
3838
>>> opt = appsi.solvers.Ipopt()
3939
>>> timer = HierarchicalTimer()
4040
>>> for p_val in np.linspace(1, 10, 100):
@@ -44,6 +44,15 @@ example of using an APPSI solver interface.
4444
>>> print(res.best_feasible_objective)
4545
>>> print(timer)
4646
47+
Alternatively, you can access the APPSI solvers through the classic
48+
``SolverFactory`` using the pattern ``appsi_solvername``.
49+
50+
.. code-block:: python
51+
52+
>>> import pyomo.environ as pyo
53+
>>> opt_ipopt = pyo.SolverFactory('appsi_ipopt')
54+
>>> opt_highs = pyo.SolverFactory('appsi_highs')
55+
4756
Extra performance improvements can be made if you know exactly what
4857
changes will be made in your model. In the example above, only
4958
parameter values are changed, so we can setup the

0 commit comments

Comments
 (0)