diff --git a/.github/workflows/release_wheel_creation.yml b/.github/workflows/release_wheel_creation.yml
index 2637a315878..419921c795d 100644
--- a/.github/workflows/release_wheel_creation.yml
+++ b/.github/workflows/release_wheel_creation.yml
@@ -27,7 +27,7 @@ jobs:
strategy:
fail-fast: true
matrix:
- os: [ubuntu-22.04, windows-latest, macos-latest]
+ os: [ubuntu-latest, windows-latest, macos-latest]
arch: [all]
wheel-version: ['cp39*', 'cp310*', 'cp311*', 'cp312*', 'cp313*']
@@ -91,7 +91,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ubuntu-22.04]
+ os: [ubuntu-latest]
arch: [all]
wheel-version: ['cp39*', 'cp310*', 'cp311*', 'cp312*', 'cp313*']
diff --git a/.github/workflows/test_branches.yml b/.github/workflows/test_branches.yml
index 3315c5250df..653ef6eba54 100644
--- a/.github/workflows/test_branches.yml
+++ b/.github/workflows/test_branches.yml
@@ -234,7 +234,7 @@ jobs:
# have support for OSX.
- name: Set up UI testing infrastructure
if: ${{ matrix.TARGET != 'osx' }}
- uses: pyvista/setup-headless-display-action@v2
+ uses: pyvista/setup-headless-display-action@v3
with:
qt: true
pyvista: false
@@ -428,6 +428,9 @@ jobs:
mkdir -p "$DOWNLOAD_DIR"
echo "TPL_DIR=$TPL_DIR" >> $GITHUB_ENV
echo "DOWNLOAD_DIR=$DOWNLOAD_DIR" >> $GITHUB_ENV
+ # Create a new PYOMO_PATH variable so we can ensure that we are actually
+ # getting the right PATH at the end
+ echo "PYOMO_PATH=$PATH" >> $GITHUB_ENV
- name: Install Ipopt
if: ${{ ! matrix.slim }}
@@ -435,6 +438,8 @@ jobs:
IPOPT_DIR=$TPL_DIR/ipopt
echo "$IPOPT_DIR" >> $GITHUB_PATH
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$IPOPT_DIR" >> $GITHUB_ENV
+ NEW_PYOMO_PATH="$IPOPT_DIR:$PYOMO_PATH"
+ echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV
mkdir -p $IPOPT_DIR
IPOPT_TAR=${DOWNLOAD_DIR}/ipopt.tar.gz
if test ! -e $IPOPT_TAR; then
@@ -511,7 +516,9 @@ jobs:
- name: Install GAMS Python bindings
if: ${{ ! matrix.slim }}
run: |
- GAMS_DIR="${env:TPL_DIR}/gams"
+ GAMS_DIR="$TPL_DIR/gams"
+ NEW_PYOMO_PATH="$GAMS_DIR:$PYOMO_PATH"
+ echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV
py_ver=$($PYTHON_EXE -c 'import sys;v="_%s%s" % sys.version_info[:2] \
;print(v if v != "_27" else "")')
if test -e $GAMS_DIR/apifiles/Python/api$py_ver; then
@@ -528,6 +535,17 @@ jobs:
$BARON_DIR = "${env:TPL_DIR}/baron"
echo "$BARON_DIR" | `
Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+ $CURRENT_PYOMO_PATH="${env:PYOMO_PATH}"
+ # Prepend BARON_DIR with appropriate path separator
+ if ( "${{matrix.TARGET}}" -eq "win" ) {
+ $PATH_SEPARATOR = ";"
+ } else {
+ $PATH_SEPARATOR = ":"
+ }
+ $NEW_PYOMO_PATH = "$BARON_DIR$PATH_SEPARATOR$CURRENT_PYOMO_PATH"
+ echo "New PYOMO_PATH: $NEW_PYOMO_PATH"
+ echo "PYOMO_PATH=$NEW_PYOMO_PATH" | `
+ Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
$URL = "https://minlp-downloads.nyc3.cdn.digitaloceanspaces.com/xecs/baron/current/"
if ( "${{matrix.TARGET}}" -eq "win" ) {
$INSTALLER = "${env:DOWNLOAD_DIR}/baron_install.exe"
@@ -562,6 +580,8 @@ jobs:
run: |
GJH_DIR="$TPL_DIR/gjh"
echo "${GJH_DIR}" >> $GITHUB_PATH
+ NEW_PYOMO_PATH="$GJH_DIR:$PYOMO_PATH"
+ echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV
INSTALL_DIR="${DOWNLOAD_DIR}/gjh"
if test ! -e "$INSTALL_DIR/bin"; then
mkdir -p "$INSTALL_DIR"
@@ -637,6 +657,11 @@ jobs:
- name: Report pyomo plugin information
run: |
+ # MRM / Jan 9, 2025: We update the PATH manually to make sure we
+ # capture all of our changes. This is necessary because of an
+ # issue with how the PATH rearranges on Windows.
+ # Issue: https://github.com/actions/runner-images/issues/11328
+ export PATH=$PYOMO_PATH
echo "$PATH"
pyomo help --solvers || exit 1
pyomo help --transformations || exit 1
@@ -645,6 +670,7 @@ jobs:
- name: Run Pyomo tests
if: matrix.mpi == 0
run: |
+ export PATH=$PYOMO_PATH
$PYTHON_EXE -m pytest -v \
-W ignore::Warning ${{matrix.category}} \
pyomo `pwd`/pyomo-model-libraries \
diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml
index 98ec7fd933b..2506573db4d 100644
--- a/.github/workflows/test_pr_and_main.yml
+++ b/.github/workflows/test_pr_and_main.yml
@@ -152,7 +152,7 @@ jobs:
PACKAGES: pyutilib
- os: ubuntu-latest
- python: pypy-3.9
+ python: 'pypy-3.10'
skip_doctest: 1
TARGET: linux
PYENV: pip
@@ -266,7 +266,7 @@ jobs:
# have support for OSX.
- name: Set up UI testing infrastructure
if: ${{ matrix.TARGET != 'osx' }}
- uses: pyvista/setup-headless-display-action@v2
+ uses: pyvista/setup-headless-display-action@v3
with:
qt: true
pyvista: false
@@ -460,6 +460,9 @@ jobs:
mkdir -p "$DOWNLOAD_DIR"
echo "TPL_DIR=$TPL_DIR" >> $GITHUB_ENV
echo "DOWNLOAD_DIR=$DOWNLOAD_DIR" >> $GITHUB_ENV
+ # Create a new PYOMO_PATH variable so we can ensure that we are actually
+ # getting the right PATH at the end
+ echo "PYOMO_PATH=$PATH" >> $GITHUB_ENV
- name: Install Ipopt
if: ${{ ! matrix.slim }}
@@ -467,6 +470,8 @@ jobs:
IPOPT_DIR=$TPL_DIR/ipopt
echo "$IPOPT_DIR" >> $GITHUB_PATH
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$IPOPT_DIR" >> $GITHUB_ENV
+ NEW_PYOMO_PATH="$IPOPT_DIR:$PYOMO_PATH"
+ echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV
mkdir -p $IPOPT_DIR
IPOPT_TAR=${DOWNLOAD_DIR}/ipopt.tar.gz
if test ! -e $IPOPT_TAR; then
@@ -543,7 +548,9 @@ jobs:
- name: Install GAMS Python bindings
if: ${{ ! matrix.slim }}
run: |
- GAMS_DIR="${env:TPL_DIR}/gams"
+ GAMS_DIR="$TPL_DIR/gams"
+ NEW_PYOMO_PATH="$GAMS_DIR:$PYOMO_PATH"
+ echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV
py_ver=$($PYTHON_EXE -c 'import sys;v="_%s%s" % sys.version_info[:2] \
;print(v if v != "_27" else "")')
if test -e $GAMS_DIR/apifiles/Python/api$py_ver; then
@@ -560,6 +567,17 @@ jobs:
$BARON_DIR = "${env:TPL_DIR}/baron"
echo "$BARON_DIR" | `
Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+ $CURRENT_PYOMO_PATH="${env:PYOMO_PATH}"
+ # Prepend BARON_DIR with appropriate path separator
+ if ( "${{matrix.TARGET}}" -eq "win" ) {
+ $PATH_SEPARATOR = ";"
+ } else {
+ $PATH_SEPARATOR = ":"
+ }
+ $NEW_PYOMO_PATH = "$BARON_DIR$PATH_SEPARATOR$CURRENT_PYOMO_PATH"
+ echo "New PYOMO_PATH: $NEW_PYOMO_PATH"
+ echo "PYOMO_PATH=$NEW_PYOMO_PATH" | `
+ Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
$URL = "https://minlp-downloads.nyc3.cdn.digitaloceanspaces.com/xecs/baron/current/"
if ( "${{matrix.TARGET}}" -eq "win" ) {
$INSTALLER = "${env:DOWNLOAD_DIR}/baron_install.exe"
@@ -594,6 +612,8 @@ jobs:
run: |
GJH_DIR="$TPL_DIR/gjh"
echo "${GJH_DIR}" >> $GITHUB_PATH
+ NEW_PYOMO_PATH="$GJH_DIR:$PYOMO_PATH"
+ echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV
INSTALL_DIR="${DOWNLOAD_DIR}/gjh"
if test ! -e "$INSTALL_DIR/bin"; then
mkdir -p "$INSTALL_DIR"
@@ -670,6 +690,11 @@ jobs:
- name: Report pyomo plugin information
run: |
+ # MRM / Jan 9, 2025: We update the PATH manually to make sure we
+ # capture all of our changes. This is necessary because of an
+ # issue with how the PATH rearranges on Windows.
+ # Issue: https://github.com/actions/runner-images/issues/11328
+ export PATH=$PYOMO_PATH
echo "$PATH"
pyomo help --solvers || exit 1
pyomo help --transformations || exit 1
@@ -678,6 +703,7 @@ jobs:
- name: Run Pyomo tests
if: matrix.mpi == 0
run: |
+ export PATH=$PYOMO_PATH
$PYTHON_EXE -m pytest -v \
-W ignore::Warning ${{matrix.category}} \
pyomo `pwd`/pyomo-model-libraries \
diff --git a/README.md b/README.md
index 1cb773788f2..45ccce5b769 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ Pyomo is available under the BSD License - see the
Pyomo is currently tested with the following Python implementations:
* CPython: 3.9, 3.10, 3.11, 3.12, 3.13
-* PyPy: 3.9
+* PyPy: 3.10
_Testing and support policy_:
diff --git a/doc/OnlineDocs/explanation/analysis/doe/doe.rst b/doc/OnlineDocs/explanation/analysis/doe/doe.rst
index f80878b67eb..05d9d867e2b 100644
--- a/doc/OnlineDocs/explanation/analysis/doe/doe.rst
+++ b/doc/OnlineDocs/explanation/analysis/doe/doe.rst
@@ -3,7 +3,7 @@ Pyomo.DoE
**Pyomo.DoE** (Pyomo Design of Experiments) is a Python library for model-based design of experiments using science-based models.
-Pyomo.DoE was developed by **Jialu Wang** and **Alexander W. Dowling** at the University of Notre Dame as part of the `Carbon Capture Simulation for Industry Impact (CCSI2) `_.
+Pyomo.DoE was developed by **Jialu Wang** and **Alexander W. Dowling** at the University of Notre Dame as part of the `Carbon Capture Simulation for Industry Impact (CCSI2) `_.
project, funded through the U.S. Department Of Energy Office of Fossil Energy.
If you use Pyomo.DoE, please cite:
diff --git a/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst b/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst
index 17c0e765541..6d3bbea426a 100644
--- a/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst
+++ b/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst
@@ -67,6 +67,18 @@ And finally we call sIPOPT or k_aug:
>>> m_sipopt = sensitivity_calculation('sipopt', m, [m.eta1, m.eta2], [m.perturbed_eta1, m.perturbed_eta2], tee=False)
>>> m_kaug_dsdp = sensitivity_calculation('k_aug', m, [m.eta1, m.eta2], [m.perturbed_eta1, m.perturbed_eta2], tee=False)
+.. testcode:: python
+ :skipif: not sipopt_available or not k_aug_available or not dot_sens_available
+ :hide:
+
+ # The x3 result can come back -0.000 depending on the platform or
+ # solver version; map it so that tests don't fail.
+ for _m in (m, m_sipopt, m_kaug_dsdp):
+ if f'{_m.x3():.3f}' == '-0.000':
+ _m.x3 = 0.
+ if f'{m_sipopt.sens_sol_state_1[m_sipopt.x3]:.3f}' == '-0.000':
+ m_sipopt.sens_sol_state_1[m_sipopt.x3] = 0.
+
The first argument specifies the method, either 'sipopt' or 'k_aug'. The second argument is the Pyomo model. The third argument is a list of the original parameters. The fourth argument is a list of the perturbed parameters. It's important that these two lists are the same length and in the same order.
First, we can inspect the initial point:
@@ -138,7 +150,7 @@ Note that k_aug does not save the solution with the original parameter values. F
x2 = 0.667
>>> print("x3 = %0.3f" % x3)
- x3 = -0.000
+ x3 = 0.000
# *k_aug*
# New parameter values:
@@ -162,7 +174,7 @@ Note that k_aug does not save the solution with the original parameter values. F
x2 = 0.667
>>> print("x3 = %0.3f" % x3)
- x3 = -0.000
+ x3 = 0.000
Installing sIPOPT and k_aug
diff --git a/pyomo/common/config.py b/pyomo/common/config.py
index b6ff0ebfee3..ddeac28e521 100644
--- a/pyomo/common/config.py
+++ b/pyomo/common/config.py
@@ -1840,7 +1840,11 @@ def __call__(
assert default is NOTSET
else:
fields += ('domain',)
- kwds['default'] = self.value() if default is NOTSET else default
+ if default is NOTSET:
+ default = self.value()
+ if default is NOTSET:
+ default = None
+ kwds['default'] = default
assert implicit is NOTSET
assert implicit_domain is NOTSET
for field in fields:
diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py
index 5f3151961fb..3a616b714b8 100644
--- a/pyomo/contrib/doe/doe.py
+++ b/pyomo/contrib/doe/doe.py
@@ -1458,7 +1458,7 @@ def compute_FIM_full_factorial(
}
)
- succeses = 0
+ successes = 0
failures = 0
total_points = np.prod(
np.array([len(v) for k, v in design_ranges_enum.items()])
@@ -1477,14 +1477,14 @@ def compute_FIM_full_factorial(
# Compute FIM with given options
try:
- curr_point = succeses + failures + 1
+ curr_point = successes + failures + 1
# Logging information for each run
self.logger.info("This is run %s out of %s.", curr_point, total_points)
# Attempt the FIM computation
self.compute_FIM(model=model, method=method)
- succeses += 1
+ successes += 1
# iteration time
iter_t = iter_timer.toc(msg=None)
diff --git a/pyomo/contrib/pynumero/algorithms/solvers/tests/test_cyipopt_solver.py b/pyomo/contrib/pynumero/algorithms/solvers/tests/test_cyipopt_solver.py
index 8a35449d94d..9578be510a7 100644
--- a/pyomo/contrib/pynumero/algorithms/solvers/tests/test_cyipopt_solver.py
+++ b/pyomo/contrib/pynumero/algorithms/solvers/tests/test_cyipopt_solver.py
@@ -11,7 +11,7 @@
import pyomo.common.unittest as unittest
import pyomo.environ as pyo
-import os
+from pyomo.common.tempfiles import TempfileManager
from pyomo.contrib.pynumero.dependencies import (
numpy as np,
@@ -219,24 +219,25 @@ def test_model1_with_scaling(self):
m.scaling_factor[m.d] = 3.0 # scale the inequality constraint
m.scaling_factor[m.x[1]] = 4.0 # scale one of the x variables
- cynlp = CyIpoptNLP(PyomoNLP(m))
- options = {
- 'nlp_scaling_method': 'user-scaling',
- 'output_file': '_cyipopt-scaling.log',
- 'file_print_level': 10,
- 'max_iter': 0,
- }
- solver = CyIpoptSolver(cynlp, options=options)
- x, info = solver.solve()
-
- with open('_cyipopt-scaling.log', 'r') as fd:
- solver_trace = fd.read()
- cynlp.close()
- os.remove('_cyipopt-scaling.log')
-
- # check for the following strings in the log and then delete the log
+ with TempfileManager.new_context() as temp:
+ cynlp = CyIpoptNLP(PyomoNLP(m))
+ logfile = temp.create_tempfile('_cyipopt-scaling.log')
+ options = {
+ 'nlp_scaling_method': 'user-scaling',
+ 'output_file': logfile,
+ 'file_print_level': 10,
+ 'max_iter': 0,
+ }
+ solver = CyIpoptSolver(cynlp, options=options)
+ x, info = solver.solve()
+ cynlp.close()
+
+ with open(logfile, 'r') as fd:
+ solver_trace = fd.read()
+
+ # check for the following strings in the log
self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
- self.assertIn('output_file = _cyipopt-scaling.log', solver_trace)
+ self.assertIn(f"output_file = {logfile}", solver_trace)
self.assertIn('objective scaling factor = 1e-06', solver_trace)
self.assertIn('x scaling provided', solver_trace)
self.assertIn('c scaling provided', solver_trace)
diff --git a/pyomo/contrib/pynumero/algorithms/solvers/tests/test_pyomo_ext_cyipopt.py b/pyomo/contrib/pynumero/algorithms/solvers/tests/test_pyomo_ext_cyipopt.py
index 0036a6b3623..5cb0fef91ba 100644
--- a/pyomo/contrib/pynumero/algorithms/solvers/tests/test_pyomo_ext_cyipopt.py
+++ b/pyomo/contrib/pynumero/algorithms/solvers/tests/test_pyomo_ext_cyipopt.py
@@ -9,9 +9,9 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________
-import os
import pyomo.common.unittest as unittest
import pyomo.environ as pyo
+from pyomo.common.tempfiles import TempfileManager
from pyomo.contrib.pynumero.dependencies import (
numpy as np,
@@ -157,33 +157,33 @@ def test_pyomo_external_model_scaling(self):
m.scaling_factor[m.F_con] = 8.0 # scale the pyomo constraint
m.scaling_factor[m.Pin_con] = 9.0 # scale the pyomo constraint
- cyipopt_problem = PyomoExternalCyIpoptProblem(
- pyomo_model=m,
- ex_input_output_model=PressureDropModel(),
- inputs=[m.Pin, m.c1, m.c2, m.F],
- outputs=[m.P1, m.P2],
- outputs_eqn_scaling=[10.0, 11.0],
- nl_file_options={'file_determinism': 2},
- )
-
- # solve the problem
- options = {
- 'hessian_approximation': 'limited-memory',
- 'nlp_scaling_method': 'user-scaling',
- 'output_file': '_cyipopt-pyomo-ext-scaling.log',
- 'file_print_level': 10,
- 'max_iter': 0,
- }
- solver = CyIpoptSolver(cyipopt_problem, options=options)
- x, info = solver.solve(tee=False)
-
- with open('_cyipopt-pyomo-ext-scaling.log', 'r') as fd:
- solver_trace = fd.read()
- cyipopt_problem.close()
- os.remove('_cyipopt-pyomo-ext-scaling.log')
+ with TempfileManager.new_context() as temp:
+ cyipopt_problem = PyomoExternalCyIpoptProblem(
+ pyomo_model=m,
+ ex_input_output_model=PressureDropModel(),
+ inputs=[m.Pin, m.c1, m.c2, m.F],
+ outputs=[m.P1, m.P2],
+ outputs_eqn_scaling=[10.0, 11.0],
+ nl_file_options={'file_determinism': 2},
+ )
+ logfile = temp.create_tempfile('_cyipopt-pyomo-ext-scaling.log')
+ # solve the problem
+ options = {
+ 'hessian_approximation': 'limited-memory',
+ 'nlp_scaling_method': 'user-scaling',
+ 'output_file': logfile,
+ 'file_print_level': 10,
+ 'max_iter': 0,
+ }
+ solver = CyIpoptSolver(cyipopt_problem, options=options)
+ x, info = solver.solve(tee=False)
+ cyipopt_problem.close()
+
+ with open(logfile, 'r') as fd:
+ solver_trace = fd.read()
self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
- self.assertIn('output_file = _cyipopt-pyomo-ext-scaling.log', solver_trace)
+ self.assertIn(f"output_file = {logfile}", solver_trace)
self.assertIn('objective scaling factor = 0.1', solver_trace)
self.assertIn('x scaling provided', solver_trace)
self.assertIn('c scaling provided', solver_trace)
@@ -232,35 +232,33 @@ def test_pyomo_external_model_ndarray_scaling(self):
m.scaling_factor[m.Pin_con] = 9.0 # scale the pyomo constraint
# test that this all works with ndarray input as well
- cyipopt_problem = PyomoExternalCyIpoptProblem(
- pyomo_model=m,
- ex_input_output_model=PressureDropModel(),
- inputs=[m.Pin, m.c1, m.c2, m.F],
- outputs=[m.P1, m.P2],
- outputs_eqn_scaling=np.asarray([10.0, 11.0], dtype=np.float64),
- nl_file_options={'file_determinism': 2},
- )
-
- # solve the problem
- options = {
- 'hessian_approximation': 'limited-memory',
- 'nlp_scaling_method': 'user-scaling',
- 'output_file': '_cyipopt-pyomo-ext-scaling-ndarray.log',
- 'file_print_level': 10,
- 'max_iter': 0,
- }
- solver = CyIpoptSolver(cyipopt_problem, options=options)
- x, info = solver.solve(tee=False)
-
- with open('_cyipopt-pyomo-ext-scaling-ndarray.log', 'r') as fd:
- solver_trace = fd.read()
- cyipopt_problem.close()
- os.remove('_cyipopt-pyomo-ext-scaling-ndarray.log')
+ with TempfileManager.new_context() as temp:
+ cyipopt_problem = PyomoExternalCyIpoptProblem(
+ pyomo_model=m,
+ ex_input_output_model=PressureDropModel(),
+ inputs=[m.Pin, m.c1, m.c2, m.F],
+ outputs=[m.P1, m.P2],
+ outputs_eqn_scaling=np.asarray([10.0, 11.0], dtype=np.float64),
+ nl_file_options={'file_determinism': 2},
+ )
+ logfile = temp.create_tempfile('_cyipopt-pyomo-ext-scaling-ndarray.log')
+ # solve the problem
+ options = {
+ 'hessian_approximation': 'limited-memory',
+ 'nlp_scaling_method': 'user-scaling',
+ 'output_file': logfile,
+ 'file_print_level': 10,
+ 'max_iter': 0,
+ }
+ solver = CyIpoptSolver(cyipopt_problem, options=options)
+ x, info = solver.solve(tee=False)
+ cyipopt_problem.close()
+
+ with open(logfile, 'r') as fd:
+ solver_trace = fd.read()
self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
- self.assertIn(
- 'output_file = _cyipopt-pyomo-ext-scaling-ndarray.log', solver_trace
- )
+ self.assertIn(f'output_file = {logfile}', solver_trace)
self.assertIn('objective scaling factor = 0.1', solver_trace)
self.assertIn('x scaling provided', solver_trace)
self.assertIn('c scaling provided', solver_trace)
diff --git a/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py b/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py
index 2df43c1e797..f735e98b026 100644
--- a/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py
+++ b/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py
@@ -10,14 +10,16 @@
# ___________________________________________________________________________
import os.path
+from io import StringIO
+import logging
+
from pyomo.common.fileutils import this_file_dir, import_file
+from pyomo.common.tempfiles import TempfileManager
import pyomo.common.unittest as unittest
import pyomo.environ as pyo
from pyomo.common.dependencies import attempt_import
from pyomo.common.log import LoggingIntercept
from pyomo.opt import TerminationCondition
-from io import StringIO
-import logging
from pyomo.contrib.pynumero.dependencies import (
numpy as np,
@@ -87,30 +89,34 @@ def test_external_grey_box_react_example_maximize_cb_outputs_scaling(self):
'maximize_cb_ratio_residuals.py',
)
)
- aoptions = {
- 'nlp_scaling_method': 'user-scaling',
- 'output_file': '_cyipopt-external-greybox-react-scaling.log',
- 'file_print_level': 10,
- }
- m = ex.maximize_cb_ratio_residuals_with_output_scaling(
- additional_options=aoptions
- )
- self.assertAlmostEqual(pyo.value(m.reactor.inputs['sv']), 1.26541996, places=3)
- self.assertAlmostEqual(
- pyo.value(m.reactor.inputs['cb']), 1071.7410089, places=2
- )
- self.assertAlmostEqual(
- pyo.value(m.reactor.outputs['cb_ratio']), 0.15190409266, places=3
- )
- with open('_cyipopt-external-greybox-react-scaling.log', 'r') as fd:
- solver_trace = fd.read()
- os.remove('_cyipopt-external-greybox-react-scaling.log')
+ with TempfileManager.new_context() as temp:
+ logfile = temp.create_tempfile(
+ '_cyipopt-external-greybox-react-scaling.log'
+ )
+ aoptions = {
+ 'nlp_scaling_method': 'user-scaling',
+ 'output_file': logfile,
+ 'file_print_level': 10,
+ }
+ m = ex.maximize_cb_ratio_residuals_with_output_scaling(
+ additional_options=aoptions
+ )
+ self.assertAlmostEqual(
+ pyo.value(m.reactor.inputs['sv']), 1.26541996, places=3
+ )
+ self.assertAlmostEqual(
+ pyo.value(m.reactor.inputs['cb']), 1071.7410089, places=2
+ )
+ self.assertAlmostEqual(
+ pyo.value(m.reactor.outputs['cb_ratio']), 0.15190409266, places=3
+ )
+
+ with open(logfile, 'r') as fd:
+ solver_trace = fd.read()
self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
- self.assertIn(
- 'output_file = _cyipopt-external-greybox-react-scaling.log', solver_trace
- )
+ self.assertIn(f'output_file = {logfile}', solver_trace)
self.assertIn('objective scaling factor = 1', solver_trace)
self.assertIn('x scaling provided', solver_trace)
self.assertIn('c scaling provided', solver_trace)
diff --git a/pyomo/contrib/pynumero/interfaces/tests/test_external_grey_box_model.py b/pyomo/contrib/pynumero/interfaces/tests/test_external_grey_box_model.py
index 0fc342c4e40..1ea17b5e223 100644
--- a/pyomo/contrib/pynumero/interfaces/tests/test_external_grey_box_model.py
+++ b/pyomo/contrib/pynumero/interfaces/tests/test_external_grey_box_model.py
@@ -9,9 +9,9 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________
-import os
import pyomo.common.unittest as unittest
import pyomo.environ as pyo
+from pyomo.common.tempfiles import TempfileManager
from pyomo.contrib.pynumero.dependencies import (
numpy as np,
@@ -31,8 +31,11 @@
from pyomo.contrib.pynumero.algorithms.solvers.cyipopt_solver import cyipopt_available
-from ..external_grey_box import ExternalGreyBoxModel, ExternalGreyBoxBlock
-from ..pyomo_nlp import PyomoGreyBoxNLP
+from pyomo.contrib.pynumero.interfaces.external_grey_box import (
+ ExternalGreyBoxModel,
+ ExternalGreyBoxBlock,
+)
+from pyomo.contrib.pynumero.interfaces.pyomo_nlp import PyomoGreyBoxNLP
from pyomo.contrib.pynumero.interfaces.tests.compare_utils import (
check_vectors_specific_order,
check_sparse_matrix_specific_order,
@@ -2074,24 +2077,23 @@ def test_external_greybox_solve_scaling(self):
m.scaling_factor[m.mu] = 1.9
m.scaling_factor[m.pincon] = 2.2
- solver = pyo.SolverFactory('cyipopt')
- solver.config.options = {
- 'hessian_approximation': 'limited-memory',
- 'nlp_scaling_method': 'user-scaling',
- 'output_file': '_cyipopt-external-greybox-scaling.log',
- 'file_print_level': 10,
- 'max_iter': 0,
- }
- status = solver.solve(m, tee=False)
-
- with open('_cyipopt-external-greybox-scaling.log', 'r') as fd:
- solver_trace = fd.read()
- os.remove('_cyipopt-external-greybox-scaling.log')
+ with TempfileManager.new_context() as temp:
+ logfile = temp.create_tempfile('_cyipopt-external-greybox-scaling.log')
+ solver = pyo.SolverFactory('cyipopt')
+ solver.config.options = {
+ 'hessian_approximation': 'limited-memory',
+ 'nlp_scaling_method': 'user-scaling',
+ 'output_file': logfile,
+ 'file_print_level': 10,
+ 'max_iter': 0,
+ }
+ status = solver.solve(m, tee=False)
+
+ with open(logfile, 'r') as fd:
+ solver_trace = fd.read()
self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
- self.assertIn(
- 'output_file = _cyipopt-external-greybox-scaling.log', solver_trace
- )
+ self.assertIn(f'output_file = {logfile}', solver_trace)
self.assertIn('objective scaling factor = 0.1', solver_trace)
self.assertIn('x scaling provided', solver_trace)
self.assertIn('c scaling provided', solver_trace)
@@ -2149,4 +2151,4 @@ def test_external_greybox_solve_scaling(self):
if __name__ == '__main__':
- TestPyomoGreyBoxNLP().test_external_greybox_solve(self)
+ TestPyomoGreyBoxNLP().test_external_greybox_solve()
diff --git a/pyomo/contrib/pynumero/interfaces/tests/test_pyomo_grey_box_nlp.py b/pyomo/contrib/pynumero/interfaces/tests/test_pyomo_grey_box_nlp.py
index ecadf40e5cf..053c9aba4ea 100644
--- a/pyomo/contrib/pynumero/interfaces/tests/test_pyomo_grey_box_nlp.py
+++ b/pyomo/contrib/pynumero/interfaces/tests/test_pyomo_grey_box_nlp.py
@@ -9,9 +9,9 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________
-import os
import pyomo.common.unittest as unittest
import pyomo.environ as pyo
+from pyomo.common.tempfiles import TempfileManager
from pyomo.contrib.pynumero.dependencies import (
numpy as np,
@@ -2495,24 +2495,23 @@ def test_external_greybox_solve_scaling(self):
m.scaling_factor[m.mu] = 1.9
m.scaling_factor[m.pincon] = 2.2
- solver = pyo.SolverFactory('cyipopt')
- solver.config.options = {
- 'hessian_approximation': 'limited-memory',
- 'nlp_scaling_method': 'user-scaling',
- 'output_file': '_cyipopt-external-greybox-scaling.log',
- 'file_print_level': 10,
- 'max_iter': 0,
- }
- status = solver.solve(m, tee=False)
-
- with open('_cyipopt-external-greybox-scaling.log', 'r') as fd:
- solver_trace = fd.read()
- os.remove('_cyipopt-external-greybox-scaling.log')
+ with TempfileManager.new_context() as temp:
+ logfile = temp.create_tempfile('_cyipopt-external-greybox-scaling.log')
+ solver = pyo.SolverFactory('cyipopt')
+ solver.config.options = {
+ 'hessian_approximation': 'limited-memory',
+ 'nlp_scaling_method': 'user-scaling',
+ 'output_file': logfile,
+ 'file_print_level': 10,
+ 'max_iter': 0,
+ }
+ status = solver.solve(m, tee=False)
+
+ with open(logfile, 'r') as fd:
+ solver_trace = fd.read()
self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
- self.assertIn(
- 'output_file = _cyipopt-external-greybox-scaling.log', solver_trace
- )
+ self.assertIn(f'output_file = {logfile}', solver_trace)
self.assertIn('objective scaling factor = 0.1', solver_trace)
self.assertIn('x scaling provided', solver_trace)
self.assertIn('c scaling provided', solver_trace)
diff --git a/pyomo/contrib/simplification/build.py b/pyomo/contrib/simplification/build.py
index b4bec63088a..d7fac9522dc 100644
--- a/pyomo/contrib/simplification/build.py
+++ b/pyomo/contrib/simplification/build.py
@@ -63,7 +63,7 @@ def build_ginac_library(parallel=None, argv=None, env=None):
assert subprocess.run(make_cmd, cwd=cln_dir, env=env).returncode == 0
assert subprocess.run(install_cmd, cwd=cln_dir, env=env).returncode == 0
- url = 'https://www.ginac.de/ginac-1.8.7.tar.bz2'
+ url = 'https://www.ginac.de/ginac-1.8.8.tar.bz2'
ginac_dir = os.path.join(tmpdir, 'ginac')
downloader.set_destination_filename(ginac_dir)
logger.info(
diff --git a/pyomo/core/base/indexed_component.py b/pyomo/core/base/indexed_component.py
index ee1fe1e0037..4fcbd30d1ff 100644
--- a/pyomo/core/base/indexed_component.py
+++ b/pyomo/core/base/indexed_component.py
@@ -344,7 +344,7 @@ def _create_objects_for_deepcopy(self, memo, component_list):
# For indexed components, we will pre-emptively clone all
# component data objects as well (as those are the objects
# that will be referenced by things like expressions). It
- # is important to only clone "normal" ComponentData obects:
+ # is important to only clone "normal" ComponentData objects:
# so we will want to skip this for all scalar components
# (where the _data points back to self) and references
# (where the data may be stored outside this block tree and
diff --git a/pyomo/core/expr/taylor_series.py b/pyomo/core/expr/taylor_series.py
index 2658dd36ff5..7dc24f3ccf4 100644
--- a/pyomo/core/expr/taylor_series.py
+++ b/pyomo/core/expr/taylor_series.py
@@ -43,7 +43,7 @@ def taylor_series_expansion(
The method for differentiation.
order: The order of the taylor series expansion
If order is not 1, then symbolic differentiation must
- be used (differentiation.Modes.reverse_sybolic or
+ be used (differentiation.Modes.reverse_symbolic or
differentiation.Modes.sympy).
Returns
diff --git a/pyomo/solvers/plugins/solvers/cplex_direct.py b/pyomo/solvers/plugins/solvers/cplex_direct.py
index 93d8015514e..b758453df7d 100644
--- a/pyomo/solvers/plugins/solvers/cplex_direct.py
+++ b/pyomo/solvers/plugins/solvers/cplex_direct.py
@@ -846,7 +846,9 @@ def _postsolve(self):
if extract_slacks:
linear_slacks = self._solver_model.solution.get_linear_slacks()
- qudratic_slacks = self._solver_model.solution.get_quadratic_slacks()
+ quadratic_slacks = (
+ self._solver_model.solution.get_quadratic_slacks()
+ )
for i, con_name in enumerate(
self._solver_model.linear_constraints.get_names()
):
@@ -869,7 +871,7 @@ def _postsolve(self):
for i, con_name in enumerate(
self._solver_model.quadratic_constraints.get_names()
):
- soln_constraints[con_name]["Slack"] = qudratic_slacks[i]
+ soln_constraints[con_name]["Slack"] = quadratic_slacks[i]
elif self._load_solutions:
if cpxprob.solution.get_solution_type() > 0:
self.load_vars()