From c70a9dedaafbc2ccfffc995621b95042731781b9 Mon Sep 17 00:00:00 2001 From: Alasdair Gray Date: Wed, 8 Oct 2025 13:31:38 -0400 Subject: [PATCH 1/5] Minor improvements to `addConGroup` --- pyoptsparse/pyOpt_optimization.py | 51 ++++++++++++++++--------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/pyoptsparse/pyOpt_optimization.py b/pyoptsparse/pyOpt_optimization.py index 64fa6143..7f8c41fa 100644 --- a/pyoptsparse/pyOpt_optimization.py +++ b/pyoptsparse/pyOpt_optimization.py @@ -2,6 +2,7 @@ from collections import OrderedDict import copy import os +import warnings from typing import Callable, Dict, Iterable, List, Optional, Tuple, Union # External modules @@ -368,8 +369,10 @@ def addConGroup( wrt: Optional[Union[str, Iterable[str]]] = None, jac=None, ): - r"""Add a group of variables into a variable set. This is the main - function used for adding variables to pyOptSparse. + r"""Add a group of constraints into the constraint set. This is the main function used for adding constraints to + pyOptSparse. + + To define equality constraints, set both the lower and upper bounds to the same value. Parameters ---------- @@ -379,27 +382,20 @@ def addConGroup( nCon : int The number of constraints in this group - lower : scalar or array - The lower bound(s) for the constraint. If it is a scalar, - it is applied to all nCon constraints. If it is an array, - the array must be the same length as nCon. + lower : scalar or array, optional + The lower bound(s) for the constraint. If it is a scalar, it is applied to all nCon constraints. If it is an + array, the array must be of length nCon. By default no lower bound is applied. - upper : scalar or array - The upper bound(s) for the constraint. If it is a scalar, - it is applied to all nCon constraints. If it is an array, - the array must be the same length as nCon. + upper : scalar or array, optional + Identical to ``lower``, but for the upper bound(s). - scale : scalar or array + scale : scalar or array, optional + A scaling factor for the constraint. It is generally advisable to have most optimization constraint around + the same order of magnitude. By default 1.0. - A scaling factor for the constraint. It is generally - advisable to have most optimization constraint around the - same order of magnitude. - - linear : bool - Flag to specify if this constraint is linear. If the - constraint is linear, both the ``wrt`` and ``jac`` keyword - arguments must be given to specify the constant portion of - the constraint Jacobian. + linear : bool, optional + Flag to specify if this constraint is linear. If the constraint is linear, both the ``wrt`` and ``jac`` + keyword arguments must be given to specify the constant portion of the constraint Jacobian. By default False. The intercept term of linear constraints must be supplied as part of the bound information. The linear constraint :math:`g_L \leq Ax + b \leq g_U` @@ -410,12 +406,12 @@ def addConGroup( jac = {"dvName" : A, ...}, lower = gL - b, upper = gU - b - wrt : iterable (list, set, OrderedDict, array etc) - 'wrt' stand for stands for 'With Respect To'. This - specifies for what dvs have non-zero Jacobian values - for this set of constraints. The order is not important. + wrt : iterable (list, set, OrderedDict, array etc), optional + 'wrt' stand for stands for 'With Respect To'. This specifies which dvs this constrain is assumed to depend + on, and therefore which blocks of the Jacobian will have non-zero values. The order is not important. By + default the constraint is assumed to depend on all design variables. - jac : dictionary + jac : dictionary, optional For linear and sparse non-linear constraints, the constraint Jacobian must be passed in. The structure of jac dictionary is as follows: @@ -456,6 +452,11 @@ def addConGroup( the Jacobian change throughout the optimization. This stipulation is automatically checked internally. """ + if lower is None and upper is None: + warnings.warn( + f"No upper or lower bounds were given for constraint '{name}'. This constraint will have no effect.", + stacklevel=2, + ) self.finalized = False if name in self.constraints: raise KeyError(f"The supplied name '{name}' for a constraint group has already been used.") From f9e65c21a4f0ed7cd1472da56877ae42c0b525f9 Mon Sep 17 00:00:00 2001 From: Alasdair Gray Date: Wed, 8 Oct 2025 13:36:45 -0400 Subject: [PATCH 2/5] Update pyoptsparse/pyOpt_optimization.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pyoptsparse/pyOpt_optimization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyoptsparse/pyOpt_optimization.py b/pyoptsparse/pyOpt_optimization.py index 7f8c41fa..23ab3211 100644 --- a/pyoptsparse/pyOpt_optimization.py +++ b/pyoptsparse/pyOpt_optimization.py @@ -407,7 +407,7 @@ def addConGroup( jac = {"dvName" : A, ...}, lower = gL - b, upper = gU - b wrt : iterable (list, set, OrderedDict, array etc), optional - 'wrt' stand for stands for 'With Respect To'. This specifies which dvs this constrain is assumed to depend + 'wrt' stands for 'With Respect To'. This specifies which dvs this constraint is assumed to depend on, and therefore which blocks of the Jacobian will have non-zero values. The order is not important. By default the constraint is assumed to depend on all design variables. From 8dc76149f90fc7653c21684c59c13b0d07679386 Mon Sep 17 00:00:00 2001 From: Alasdair Gray Date: Wed, 8 Oct 2025 13:37:28 -0400 Subject: [PATCH 3/5] typo --- pyoptsparse/pyOpt_optimization.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyoptsparse/pyOpt_optimization.py b/pyoptsparse/pyOpt_optimization.py index 7f8c41fa..d02ccad3 100644 --- a/pyoptsparse/pyOpt_optimization.py +++ b/pyoptsparse/pyOpt_optimization.py @@ -407,9 +407,9 @@ def addConGroup( jac = {"dvName" : A, ...}, lower = gL - b, upper = gU - b wrt : iterable (list, set, OrderedDict, array etc), optional - 'wrt' stand for stands for 'With Respect To'. This specifies which dvs this constrain is assumed to depend - on, and therefore which blocks of the Jacobian will have non-zero values. The order is not important. By - default the constraint is assumed to depend on all design variables. + 'wrt' stands for 'With Respect To'. This specifies which dvs this constrain is assumed to depend on, and + therefore which blocks of the Jacobian will have non-zero values. The order is not important. By default the + constraint is assumed to depend on all design variables. jac : dictionary, optional For linear and sparse non-linear constraints, the constraint From e260c85630c1feda2339e86e8fef6e798ea76296 Mon Sep 17 00:00:00 2001 From: Alasdair Gray Date: Wed, 8 Oct 2025 13:39:03 -0400 Subject: [PATCH 4/5] `isort .` --- pyoptsparse/pyOpt_optimization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyoptsparse/pyOpt_optimization.py b/pyoptsparse/pyOpt_optimization.py index 28890d45..072e1fd5 100644 --- a/pyoptsparse/pyOpt_optimization.py +++ b/pyoptsparse/pyOpt_optimization.py @@ -2,8 +2,8 @@ from collections import OrderedDict import copy import os -import warnings from typing import Callable, Dict, Iterable, List, Optional, Tuple, Union +import warnings # External modules import numpy as np From 1e5f1fb6939741d7998adf8af529b0abc3b68eb9 Mon Sep 17 00:00:00 2001 From: Alasdair Gray Date: Wed, 8 Oct 2025 22:40:07 -0400 Subject: [PATCH 5/5] Update wrt parameter description to specify str type --- pyoptsparse/pyOpt_optimization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyoptsparse/pyOpt_optimization.py b/pyoptsparse/pyOpt_optimization.py index 072e1fd5..0f3da1a6 100644 --- a/pyoptsparse/pyOpt_optimization.py +++ b/pyoptsparse/pyOpt_optimization.py @@ -406,7 +406,7 @@ def addConGroup( jac = {"dvName" : A, ...}, lower = gL - b, upper = gU - b - wrt : iterable (list, set, OrderedDict, array etc), optional + wrt : iterable of str, optional 'wrt' stands for 'With Respect To'. This specifies which dvs this constraint is assumed to depend on, and therefore which blocks of the Jacobian will have non-zero values. The order is not important. By default the constraint is assumed to depend on all design variables.