Source code for pyomo.contrib.appsi.writers.nl_writer

#  ___________________________________________________________________________
#
#  Pyomo: Python Optimization Modeling Objects
#  Copyright (c) 2008-2024
#  National Technology and Engineering Solutions of Sandia, LLC
#  Under the terms of Contract DE-NA0003525 with National Technology and
#  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain
#  rights in this software.
#  This software is distributed under the 3-clause BSD License.
#  ___________________________________________________________________________

from typing import List
from pyomo.core.base.param import ParamData
from pyomo.core.base.var import VarData
from pyomo.core.base.constraint import ConstraintData
from pyomo.core.base.objective import ObjectiveData
from pyomo.core.base.sos import SOSConstraintData
from pyomo.core.base.block import BlockData
from pyomo.repn.standard_repn import generate_standard_repn
from pyomo.core.expr.numvalue import value
from pyomo.contrib.appsi.base import PersistentBase
from pyomo.core.base import SymbolMap, NumericLabeler, TextLabeler
from pyomo.common.timing import HierarchicalTimer
from pyomo.core.kernel.objective import minimize
from .config import WriterConfig
from pyomo.common.collections import OrderedSet
import os
from ..cmodel import cmodel, cmodel_available
from pyomo.repn.plugins.ampl.ampl_ import set_pyomo_amplfunc_env


[docs] class NLWriter(PersistentBase):
[docs] def __init__(self, only_child_vars=False): super(NLWriter, self).__init__(only_child_vars=only_child_vars) self._config = WriterConfig() self._writer = None self._symbol_map = SymbolMap() self._var_labeler = None self._con_labeler = None self._param_labeler = None self._pyomo_var_to_solver_var_map = dict() self._pyomo_con_to_solver_con_map = dict() self._solver_var_to_pyomo_var_map = dict() self._solver_con_to_pyomo_con_map = dict() self._pyomo_param_to_solver_param_map = dict() self._expr_types = None
@property def config(self): return self._config @config.setter def config(self, val: WriterConfig): self._config = val @property def symbol_map(self): return self._symbol_map def set_instance(self, model): saved_config = self.config saved_update_config = self.update_config self.__init__(only_child_vars=self._only_child_vars) self.config = saved_config self.update_config = saved_update_config self._model = model self._expr_types = cmodel.PyomoExprTypes() if self.config.symbolic_solver_labels: self._var_labeler = TextLabeler() self._con_labeler = TextLabeler() self._param_labeler = TextLabeler() self._writer = cmodel.NLWriter() self.add_block(model) if self._objective is None: self.set_objective(None) self._set_pyomo_amplfunc_env() def _add_variables(self, variables: List[VarData]): if self.config.symbolic_solver_labels: set_name = True symbol_map = self._symbol_map labeler = self._var_labeler else: set_name = False symbol_map = None labeler = None cmodel.process_pyomo_vars( self._expr_types, variables, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, self._vars, self._solver_var_to_pyomo_var_map, set_name, symbol_map, labeler, False, ) def _add_params(self, params: List[ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] cp.value = p.value self._pyomo_param_to_solver_param_map[id(p)] = cp if self.config.symbolic_solver_labels: for ndx, p in enumerate(params): cp = cparams[ndx] cp.name = self._symbol_map.getSymbol(p, self._param_labeler) def _add_constraints(self, cons: List[ConstraintData]): cmodel.process_nl_constraints( self._writer, self._expr_types, cons, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, self._active_constraints, self._pyomo_con_to_solver_con_map, self._solver_con_to_pyomo_con_map, ) if self.config.symbolic_solver_labels: for c, cc in self._pyomo_con_to_solver_con_map.items(): cc.name = self._symbol_map.getSymbol(c, self._con_labeler) def _add_sos_constraints(self, cons: List[SOSConstraintData]): if len(cons) != 0: raise NotImplementedError('NL writer does not support SOS constraints') def _remove_constraints(self, cons: List[ConstraintData]): if self.config.symbolic_solver_labels: for c in cons: self._symbol_map.removeSymbol(c) self._con_labeler.remove_obj(c) for c in cons: cc = self._pyomo_con_to_solver_con_map.pop(c) self._writer.remove_constraint(cc) del self._solver_con_to_pyomo_con_map[cc] def _remove_sos_constraints(self, cons: List[SOSConstraintData]): if len(cons) != 0: raise NotImplementedError('NL writer does not support SOS constraints') def _remove_variables(self, variables: List[VarData]): if self.config.symbolic_solver_labels: for v in variables: self._symbol_map.removeSymbol(v) self._var_labeler.remove_obj(v) for v in variables: cvar = self._pyomo_var_to_solver_var_map.pop(id(v)) del self._solver_var_to_pyomo_var_map[cvar] def _remove_params(self, params: List[ParamData]): if self.config.symbolic_solver_labels: for p in params: self._symbol_map.removeSymbol(p) self._param_labeler.remove_obj(p) for p in params: del self._pyomo_param_to_solver_param_map[id(p)] def _update_variables(self, variables: List[VarData]): cmodel.process_pyomo_vars( self._expr_types, variables, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, self._vars, self._solver_var_to_pyomo_var_map, False, None, None, True, ) def update_params(self): for p_id, p in self._params.items(): cp = self._pyomo_param_to_solver_param_map[p_id] cp.value = p.value def _set_objective(self, obj: ObjectiveData): if obj is None: const = cmodel.Constant(0) lin_vars = list() lin_coef = list() nonlin = cmodel.Constant(0) sense = 0 else: pyomo_expr_types = cmodel.PyomoExprTypes() repn = generate_standard_repn( obj.expr, compute_values=False, quadratic=False ) const = cmodel.appsi_expr_from_pyomo_expr( repn.constant, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, pyomo_expr_types, ) lin_vars = [ self._pyomo_var_to_solver_var_map[id(i)] for i in repn.linear_vars ] lin_coef = [ cmodel.appsi_expr_from_pyomo_expr( i, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, pyomo_expr_types, ) for i in repn.linear_coefs ] if repn.nonlinear_expr is None: nonlin = cmodel.appsi_expr_from_pyomo_expr( 0, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, pyomo_expr_types, ) else: nonlin = cmodel.appsi_expr_from_pyomo_expr( repn.nonlinear_expr, self._pyomo_var_to_solver_var_map, self._pyomo_param_to_solver_param_map, pyomo_expr_types, ) if obj.sense is minimize: sense = 0 else: sense = 1 cobj = cmodel.NLObjective(const, lin_coef, lin_vars, nonlin) cobj.sense = sense self._writer.objective = cobj def write(self, model: BlockData, filename: str, timer: HierarchicalTimer = None): if timer is None: timer = HierarchicalTimer() if model is not self._model: timer.start('set_instance') self.set_instance(model) timer.stop('set_instance') else: timer.start('update') self.update(timer=timer) for cv, v in self._solver_var_to_pyomo_var_map.items(): if v.value is not None: cv.value = v.value timer.stop('update') timer.start('write file') self._writer.write(filename) timer.stop('write file') def update(self, timer: HierarchicalTimer = None): super(NLWriter, self).update(timer=timer) self._set_pyomo_amplfunc_env() def get_ordered_vars(self): return [ self._solver_var_to_pyomo_var_map[i] for i in self._writer.get_solve_vars() ] def get_ordered_cons(self): return [ self._solver_con_to_pyomo_con_map[i] for i in self._writer.get_solve_cons() ] def get_active_objective(self): return self._objective def _set_pyomo_amplfunc_env(self): if self._external_functions: external_Libs = OrderedSet() for con, ext_funcs in self._external_functions.items(): external_Libs.update([i._fcn._library for i in ext_funcs]) set_pyomo_amplfunc_env(external_Libs) elif "PYOMO_AMPLFUNC" in os.environ: del os.environ["PYOMO_AMPLFUNC"]