Source code for pwrs.mp_opt_model.ipopt_options
# Copyright (c) 1996-2016, Power Systems Engineering Research Center (PSERC) by Ray Zimmerman, PSERC Cornell
# Modifications Copyright (c) 2026, Liangyu Zhang
# SPDX-License-Identifier: BSD-3-Clause
from collections.abc import Mapping
from ..corex import MatpowerConfig, SolverOptions
from ..corex.solver_options import merge_nested_options
[docs]
def ipopt_options(
overrides: Mapping[str, object] | None = None,
mpopt: MatpowerConfig | Mapping[str, object] | str | None = None,
) -> SolverOptions:
"""Build an IPOPT options dict.
Parameters
----------
overrides : dict, optional
Values applied after the defaults and any ``mpopt["ipopt"]["opts"]``
overrides.
mpopt : dict or str, optional
MATPOWER options dict or a user option function name. User option
functions are not implemented in the current Python port.
Returns
-------
dict
Options dict for the IPOPT backend.
"""
verbose = 2
fname = ""
have_mpopt = False
ipopt_config: Mapping[str, object] = {}
violation = 5e-6
if isinstance(mpopt, str):
fname = mpopt
elif isinstance(mpopt, MatpowerConfig):
have_mpopt = True
verbose = mpopt.verbose
violation = mpopt.opf.violation
if mpopt.ipopt is not None:
ipopt_config = mpopt.ipopt.to_dict()
fname = mpopt.ipopt.opt_fname
if not fname and mpopt.ipopt.opt:
fname = f"ipopt_user_options_{mpopt.ipopt.opt}"
elif isinstance(mpopt, Mapping):
have_mpopt = True
configured_verbose = mpopt.get("verbose")
if isinstance(configured_verbose, int):
verbose = configured_verbose
opf = mpopt.get("opf")
if isinstance(opf, Mapping):
configured_violation = opf.get("violation")
if isinstance(configured_violation, (int, float)):
violation = float(configured_violation)
candidate = mpopt.get("ipopt")
if isinstance(candidate, Mapping):
ipopt_config = candidate
configured_fname = candidate.get("opt_fname")
if isinstance(configured_fname, str):
fname = configured_fname
configured_opt = candidate.get("opt")
if not fname and isinstance(configured_opt, int) and configured_opt:
fname = f"ipopt_user_options_{configured_opt}"
if verbose:
print_level = min(12, int(verbose) * 2 + 1)
else:
print_level = 0
opt: SolverOptions = {
"print_level": print_level,
"tol": 1e-8,
"max_iter": 250,
"dual_inf_tol": 0.1,
"compl_inf_tol": 1e-5,
"acceptable_tol": 1e-8,
"acceptable_compl_inf_tol": 1e-3,
"mu_strategy": "adaptive",
}
if have_mpopt:
opt["constr_viol_tol"] = violation
opt["acceptable_constr_viol_tol"] = violation * 100
if fname:
raise NotImplementedError("ipopt_options user option functions are not yet implemented")
if have_mpopt:
mp_ipopt_opt = ipopt_config.get("opts")
if isinstance(mp_ipopt_opt, Mapping):
merge_nested_options(opt, mp_ipopt_opt)
if overrides is not None:
merge_nested_options(opt, overrides)
return opt